/** @file   controls.c
 *  @brief  Display und Bedienelemente
 *  @author Tom, DL7BJ
 */

#include "controls.h"

// Stringkonstanten für das Display

// Programm Info
const char Trx1[]          = "TRX 1";
const char Trx2[]          = "TRX 2";
const char IambicA[]       = "Iambic A";
const char IambicB[]       = "Iambic B";
const char Ultimatic[]     = "Ultimat.";
const char Memory[]        = "Memory";
const char Ratio[]         = "Ratio";
const char SpeedRatio[]    = "SpeedRatio";
const char ReverseRL[]     = " L -   R °";
const char ReverseLR[]     = " L °   R -";
const char SideToneOnOff[] = "Mithörton";
const char SideToneFreq[]  = "Frequenz";
const char RiseTime[]      = "Anstieg";
const char DebounceTime[]  = "Entprl.";
const char Yes[]           = "J";
const char No[]            = "N";
const char Hz[]            = "Hz";

void Drehencoder(void)
{
    int st = 0;
    static int last;

    if(!(bMenuCtrl.Config))
    {
        EncoderMinMax(5,50);
        st = EncoderRead(1);
        if(bConfig.WpM != st)
        {
            bConfig.WpM = st;           // neuen Wert in bConfig speichern
            bState.WpMChanged = 1;     // Status für Timer 0 setzen
            bMenuCtrl.Update = 1;       // Status für UpdateDisplay setzen
            EncoderPos = st;            // neuen Werte in EncoderPos speichern
            WpM = bConfig.WpM;          // neuen Wert in WpM übernehmen
            cli();
            StoreEEprom = 0;            // Timer 0 Variable löschen für Update EEprom
            sei();
            SetRatio(0);
        }
    }

    if((bMenuCtrl.buttonPressed == 1) && (bMenuCtrl.Config == 0))
    {
        bMenuCtrl.Config = 1;
        MenuCtrlTimer = 0;
        bMenuCtrl.buttonPressed = 0;
        EncoderPos = EncoderRead(1);
        bMenuCtrl.CurMenue = EncoderPosConfig;
        EncoderWrite(EncoderPosConfig);
        bMenuCtrl.Update = 1;
    }

    if((bMenuCtrl.buttonPressedLong == 1) && (bMenuCtrl.Config == 1))
    {
        if(bMenuCtrl.SubMenue == 1)
        {
            bMenuCtrl.SubMenue = 0;
            bMenuCtrl.Update = 1;
            bMenuCtrl.buttonPressedLong = 0;
            bMenuCtrl.m_buttonPressed = 0;
            EncoderWrite(EncoderPosSubConfig);
            Boop();
        } else {
            bMenuCtrl.Config = 0;
            bMenuCtrl.Update = 1;
            bMenuCtrl.buttonPressedLong = 0;
            bMenuCtrl.buttonPressed = 0;
            bMenuCtrl.m_buttonPressed = 0;
            MenuCtrlTimer = 0;
            EncoderPosConfig = EncoderRead(1);
            EncoderWrite(EncoderPos);
            bMenuCtrl.ClrScr = 1;
            WriteEEprom();
            Beep();
        }
    }

    if(bMenuCtrl.Config == 1)
    {
        if((!bMenuCtrl.buttonPressed) && (bMenuCtrl.SubMenue == 0))
        {
            EncoderMinMax(1,M_MAX);
            st = EncoderRead(1);
            sprintf(sdebug,"Encoder %i\r\n",st);
            if(last != st)
            {
                bMenuCtrl.CurMenue = st;
                bMenuCtrl.Update = 1;
            }
            last = st;
        }

        if(bMenuCtrl.buttonPressed)
        {
            bMenuCtrl.m_buttonPressed = 1;
            bMenuCtrl.buttonPressed = 0;
        }

        if((bMenuCtrl.m_buttonPressed == 1) && (bMenuCtrl.SubMenue == 0))
        {
            UpdateDisplay();
            bMenuCtrl.Update = 1;
            switch(bMenuCtrl.CurMenue)
            {
                case M_TRX1:
                    if(bConfig.TRX == 2)
                        bConfig.TRX = 0;
                    else
                        bConfig.TRX = 1;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_TRX2:
                    if(bConfig.TRX == 1)
                        bConfig.TRX = 0;
                    else
                        bConfig.TRX = 2;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_IAMBICA:
                    bConfig.KeyerMode = IAMBIC_A;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_IAMBICB:
                    bConfig.KeyerMode = IAMBIC_B;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_ULTIMATIC:
                    bConfig.KeyerMode = ULTIMATIC;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_REVERSE:
                    if(bConfig.Reverse == 1)
                        bConfig.Reverse = 0;
                    else
                        bConfig.Reverse = 1;
                    if(bConfig.Reverse == 1)
                        PaddleMode = PADDLE_REVERSE;
                    else
                        PaddleMode = PADDLE_NORMAL;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_RATIO:
                    bMenuCtrl.SubMenue = 1;
                    EncoderPosSubConfig = EncoderRead(1);
                break;
                case M_MEMORY:
                    bConfig.Memory = (bConfig.Memory == 1) ? 0 : 1;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_WPMBPM:
                    bConfig.WpMBpM = (bConfig.WpMBpM == 1) ? 0 : 1;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_TON:
                    if(bConfig.SidetoneEnabled == 1)
                        SidetoneDisable();
                    else 
                        SidetoneEnable();
                    bMenuCtrl.m_buttonPressed = 0;
                break;
                case M_TON_FREQ:
                    bMenuCtrl.SubMenue = 1;
                    EncoderPosSubConfig = EncoderRead(1);
                break;
                case M_RISETIME:
                    bMenuCtrl.SubMenue = 1;
                    EncoderPosSubConfig = EncoderRead(1);
                break;
                case M_DEBOUNCE:
                    bMenuCtrl.SubMenue = 1;
                    EncoderPosSubConfig = EncoderRead(1);
                break;
                case M_SPEEDRATIO:
                    bConfig.SpeedRatioEnabled = (bConfig.SpeedRatioEnabled == 1) ? 0 : 1;
                    bMenuCtrl.m_buttonPressed = 0;
                break;
            }
        }
        // Einstellungen für variable Werte
        if((bMenuCtrl.m_buttonPressed == 1) && (bMenuCtrl.SubMenue == 1))
        {
            UpdateDisplay();
            switch(bMenuCtrl.CurMenue)
            {
                case M_RATIO:
                    EncoderMinMax(15,30);
                    EncoderWrite(bConfig.Ratio);
                    st = EncoderRead(1);
                    if(st != bConfig.Ratio)
                        bMenuCtrl.Update = 1;
                    bConfig.Ratio = st; 
                    if(bConfig.Ratio > 30) bConfig.Ratio = 30;
                    if(bConfig.Ratio < 15) bConfig.Ratio = 15;
                break;
                case M_TON_FREQ:
                    EncoderMinMax(30,100);
                    EncoderWrite(bConfig.SidetoneFreq/10);
                    st = EncoderRead(1);
                    if(st != bConfig.SidetoneFreq/10)
                    {
                        bConfig.SidetoneFreq = st * 10;
                        if(bConfig.SidetoneFreq > 1000) bConfig.SidetoneFreq = 1000;
                        if(bConfig.SidetoneFreq < 300) bConfig.SidetoneFreq = 300;
                        bMenuCtrl.Update = 1;
                        Tone(bConfig.SidetoneFreq, 250);
                    }
                break;
                case M_RISETIME:
                    EncoderMinMax(1,10);
                    EncoderWrite(bConfig.RiseTime);
                    st = EncoderRead(1);
                    if(st != bConfig.RiseTime)
                    {
                        bConfig.RiseTime = st;
                        if(bConfig.RiseTime > 10) bConfig.RiseTime = 10;
                        if(bConfig.RiseTime < 1) bConfig.RiseTime = 1;
                        bMenuCtrl.Update = 1;
                    }
                break;
                case M_DEBOUNCE:
                    EncoderMinMax(1,25);
                    EncoderWrite(bConfig.DebounceTime);
                    st = EncoderRead(1);
                    if(st != bConfig.DebounceTime)
                    {
                        bConfig.DebounceTime = st;
                        if(bConfig.DebounceTime > 25) bConfig.DebounceTime = 25;
                        if(bConfig.DebounceTime < 1) bConfig.DebounceTime = 1;
                        bMenuCtrl.Update = 1;
                    }
                break;
            }
        }
   }
}


void ConfigMenue(void)
{
    char line[22];
    lcd_clrscr();
    lcd_charMode(NORMAL);
    lcd_gotoxy(0,0);
    lcd_puts(CLEARLINE);
    lcd_gotoxy(0,0);
    if(bMenuCtrl.SubMenue == 0)
        sprintf(line,"%s    - %i","Einstellungen", bMenuCtrl.CurMenue);
    else
        sprintf(line,"%s    * %i","Einstellungen", bMenuCtrl.CurMenue);
    lcd_puts(line);
    lcd_charMode(DOUBLESIZE);
    lcd_gotoxy(0,3);
    lcd_puts(CLEARLINE);
    switch(bMenuCtrl.CurMenue)
    {
        case M_TRX1:
            lcd_gotoxy(0,3);
            if((bConfig.TRX == 1) || (bConfig.TRX == 0))
                sprintf(line,"[%s]", "TRX 1");
            else
                sprintf(line," %s ", "TRX 1");
            lcd_puts(line);
        break;
        case M_TRX2:
            lcd_gotoxy(0,3);
            if((bConfig.TRX == 2) || (bConfig.TRX == 0))
                sprintf(line,"[%s]", "TRX 2");
            else
                sprintf(line," %s ", "TRX 2");
            lcd_puts(line);
        break;
        case M_IAMBICA:
            lcd_gotoxy(0,3);
            if(bConfig.KeyerMode == IAMBIC_A)
                sprintf(line,"[%s]", IambicA);
            else 
                sprintf(line," %s ", IambicA);
            lcd_puts(line);
        break;
        case M_IAMBICB:
            lcd_gotoxy(0,3);
            if(bConfig.KeyerMode == IAMBIC_B)
                sprintf(line,"[%s]", IambicB);
            else
                sprintf(line," %s ", IambicB);
            lcd_puts(line);
        break;
        case M_ULTIMATIC:
            lcd_gotoxy(0,3);
            if(bConfig.KeyerMode == ULTIMATIC)
                sprintf(line,"[%s]", Ultimatic);
            else
                sprintf(line," %s ", Ultimatic);
            lcd_puts(line);
        break;
        case M_REVERSE:
            lcd_gotoxy(0,3);
            if(bConfig.Reverse == 0)
                sprintf(line,"%s", ReverseLR);
            else
                sprintf(line,"%s", ReverseRL);
            lcd_puts(line);
        break;
        case M_RATIO:
            lcd_gotoxy(0,3);
            if(bConfig.Ratio == 30)
                sprintf(line,"%s", "Ratio 3:1");
            else
                sprintf(line,"%s %.1f", "Ratio", (float)bConfig.Ratio/10);
            lcd_puts(line);
        break;
        case M_MEMORY:
            lcd_gotoxy(0,3);
            if(bConfig.Memory == 1)
                sprintf(line,"[%s]", Memory);
            else
                sprintf(line," %s ", Memory);
            lcd_puts(line);
        break;
        case M_TON_FREQ:
            lcd_gotoxy(0,3);
            if(bConfig.SidetoneFreq == 650)
                sprintf(line,"%s", "Ton 650Hz");
            else
                sprintf(line,"%s %uHz", "Ton", bConfig.SidetoneFreq);
            lcd_puts(line);
        break;
        case M_TON:
            lcd_gotoxy(0,3);
            if(bConfig.SidetoneEnabled == 1)
                sprintf(line,"%s", "Ton an");
            else
                sprintf(line,"%s", "Ton aus");
            lcd_puts(line);
        break;
        case M_WPMBPM:
            lcd_gotoxy(0,3);
            if(bConfig.WpMBpM == 0)
                sprintf(line,"%s", "[WpM] BpM");
            else
                sprintf(line,"%s", "WpM [BpM]");
            lcd_puts(line);
        break;
        case M_RISETIME:
            lcd_gotoxy(0,3);
            sprintf(line,"%s %ims",RiseTime, bConfig.RiseTime);
            lcd_puts(line);
        break;
        case M_DEBOUNCE:
            lcd_gotoxy(0,3);
            sprintf(line,"%s %ims",DebounceTime, bConfig.DebounceTime);
            lcd_puts(line);
        break;
        case M_SPEEDRATIO:
            lcd_gotoxy(0,3);
            if(bConfig.SpeedRatioEnabled)
                sprintf(line,"[%s]","va.Ratio");
            else
                sprintf(line," %s ","va.Ratio");
            lcd_puts(line);
        break;
    }
    bMenuCtrl.Update = 0;
    lcd_charMode(NORMAL);
}
void DisplayVersion(void)
{
    lcd_init(LCD_DISP_ON);
    lcd_charMode(DOUBLESIZE);
    lcd_home();
    lcd_puts(PRG);
    lcd_gotoxy(1,2);
    lcd_puts(VER);
    lcd_gotoxy(2,4);
    lcd_puts(CALL);
    SidetoneOff();
    DelayMilliSeconds(1000);
}

/** \brief UpdateDisplay
 *
 * Aktualisierung der Anzeigen auf dem Display je nach
 * aktueller Funktion.
 *
 *  DOUBLESIZE 4x10 character
 *  NORMALSIZE 8x21 character
*/
void UpdateDisplay(void)
{
    char line[22];
    if(bMenuCtrl.Update)
    {
        if(bMenuCtrl.ClrScr)
        {
            lcd_clrscr();
            bMenuCtrl.ClrScr = 0;
            bMenuCtrl.Update = 1;
        }
        if(!(bMenuCtrl.Config))
        {
            lcd_charMode(DOUBLESIZE);
            lcd_gotoxy(4,2);
            if(bConfig.WpMBpM == 0)
                sprintf(line,"%i WpM ",bConfig.WpM);
            else
                sprintf(line,"%i BpM ", bConfig.WpM*5);
            lcd_puts(line);
            lcd_charMode(NORMAL);
            lcd_gotoxy(13,0);
            if(bConfig.KeyerMode == IAMBIC_A)
                sprintf(line,"%s", IambicA);
            if(bConfig.KeyerMode == IAMBIC_B)
                sprintf(line,"%s", IambicB);
            if(bConfig.KeyerMode == ULTIMATIC)
                sprintf(line,"%s", Ultimatic);
            lcd_puts(line);
            lcd_gotoxy(0,0);
            if(bConfig.TRX == 1)
                sprintf(line, "%s", Trx1);
            if(bConfig.TRX == 2)
                sprintf(line, "%s", Trx2);
            if(bConfig.TRX == 0)
                sprintf(line, "%s %s", Trx1, Trx2);
            lcd_puts(line);
            lcd_gotoxy(0,6);
            if(bConfig.SpeedRatioEnabled)
                sprintf(line,"Ratio auto.");
            else
                sprintf(line,"Ratio 1:%.1f", (float)bConfig.Ratio/10);
            lcd_puts(line);
            lcd_gotoxy(13,6);
            if(bConfig.Memory)
                sprintf(line,"MEM ON ");
            else
                sprintf(line,"MEM OFF");
            lcd_puts(line);
        }
        if(bMenuCtrl.Config)
        {
            ConfigMenue();
        }
    }
    bMenuCtrl.Update = 0;
}

