// Routines and Data related to settings
#include "settings.h"
#include "flash.h"
#include "io.h"

void defaultSettings(){                     //load sensible defaults
    newUartMode=UART_MODE_ASCII;
    //newUartMode=UART_MODE_ASCII_EXT;
    //newUartMode=UART_MODE_VT100;    
    newUartLE=UART_LE_CRLF;
    newBaudRate=9600;
}

void saveSettings(){
    //put in RAM image
    RAMImage[0]=newUartMode;
    RAMImage[1]=newUartLE;
    RAMImage[2]=newBaudRate;
    //save RAM image to flash
    if(saveToFlash()){
        uart_print("Save failed\r\n");
    }else{
        uart_print("Saved OK\r\n");        
    }
    
}

void loadSettings(){
    //load from flash
    loadToRAM();
    //store in working variables
    newUartMode=RAMImage[0];
    newUartLE=RAMImage[1];
    newBaudRate=RAMImage[2];
}

void doSetupMenu(){         //main menu setup routine
    int setupDone=0, menuState=0,d;
    newBaudRate=currentBaudRate;
    newUartMode=currentUartMode;
    newUartLE=currentUartLE;
    AMBER_LED=1;
    while(!setupDone){
        SYS_Tasks();                       //Harmony code- USB servicing etc
        if(menuState==0){printMenu(newUartMode,newUartLE,newBaudRate);menuState=1;}
        if(uart_available()){
            d=uart_receive();
            if(menuState==1){
                switch(d){
                    case 'X':
                    case 'x':setupDone=1;break;
                    case 'C':
                    case 'c':uart_print("Settings NOT changed. Exiting setting mode.\r\n");AMBER_LED=0;return;break;
                    case 'D':
                    case 'd':uart_print("Loaded defaults.\r\n");defaultSettings();menuState=0;break;
                    case 'L':
                    case 'l':uart_print("Loaded from FLASH.\r\n");loadSettings();menuState=0;break;
                    case 'S':
                    case 's':uart_print("Saving to FLASH.\r\n");saveSettings();menuState=0;break;
                    case '0':uart_print("Baud rate set to 9600.\r\n");newBaudRate=9600;menuState=0;break;
                    case '1':uart_print("Baud rate set to 38400.\r\n");newBaudRate=38400;menuState=0;break;
                    case '2':uart_print("Baud rate set to 115200.\r\n");newBaudRate=115200;menuState=0;break;
                    case '3':uart_print("Enter new Baud rate:");newBaudRate=0;menuState=2;break;
                    case '4':uart_print("Mode set to 7bit ASCII\r\n");newUartMode=UART_MODE_ASCII;menuState=0;break;
                    case '5':uart_print("Mode set to Extended ASCII\r\n");newUartMode=UART_MODE_ASCII_EXT;menuState=0;break;
                    case '6':uart_print("Mode set to VT100 Mode\r\n");newUartMode=UART_MODE_VT100;menuState=0;break;
                    case '7':uart_print("Line ending set to CR only\r\n");newUartLE=UART_LE_CRONLY;menuState=0;break;
                    case '8':uart_print("Line ending set to LF only\r\n");newUartLE=UART_LE_LFONLY;menuState=0;break;
                    case '9':uart_print("Line ending set to CR/LF\r\n");newUartLE=UART_LE_CRLF;menuState=0;break;
                }
            }else if(menuState==2){
                if((d>='0')&&(d<='9')){
                    newBaudRate=newBaudRate*10+d-'0';
                    uart_send(d);           //echo
                }
                if(((d==13)||(d==10))&&(newBaudRate)){                  //avoid following CR/LF on Arduino Serial monitor etc
                    uart_print("\r\nEntered:");
                    uart_printl(newBaudRate);
                    uart_print("\r\n");
                    if((newBaudRate<100)||(newBaudRate>1000000L)){      //out of range
                        uart_print("Out of range- not accepted.\r\n");
                    }else{                                              //OK
                        uart_print("Accepted.\r\n");
                    }
                    menuState=0;                                        //back up to main menu
                }
            }
        }
    }
    uart_print("Settings changed. Exiting setting mode.\r\n\r\n\r\n");
    if(currentBaudRate!=newBaudRate){     //change baud rate if necessary
        while(U1STAbits.TRMT==0){}          //wait til pending data sent at old baud rate
        uart_init(newBaudRate);
    }
    currentBaudRate=newBaudRate;
    currentUartMode=newUartMode;
    currentUartLE=newUartLE;         
    AMBER_LED=0;
}

void printMenu(uartMode m, uartLE line,uint32_t b){
    uart_print("\r\n\r\nUSB Keyboard Serial Interface\r\n");
    uart_print("-----------------------------\r\n");
    uart_print("0. Set Baud rate 9600\r\n");
    uart_print("1. Set Baud rate 38400\r\n");
    uart_print("2. Set Baud rate 115200\r\n");
    uart_print("3. Set custom Baud rate\r\n");
    uart_print("4. Set 7bit ASCII\r\n");
    uart_print("5. Set Extended ASCII\r\n");
    uart_print("6. Set VT100 Mode\r\n");
    uart_print("7. Set CR line ending\r\n");
    uart_print("8. Set LF line ending\r\n");
    uart_print("9. Set CR/LF line ending\r\n");
    uart_print("D. Load defaults (9600/ASCII/CRLF)\r\n");
    uart_print("L. Load from FLASH\r\n");
    uart_print("S. Save to FLASH\r\n");
    uart_print("X. Exit (with new settings)\r\n");
    uart_print("C. Cancel (don't change settings)\r\n");    
    uart_print("Current UART mode: ");
    switch(m){
        case UART_MODE_ASCII: uart_print("7bit ASCII\r\n");break;
        case UART_MODE_ASCII_EXT: uart_print("Extended ASCII\r\n");break;
        case UART_MODE_VT100: uart_print("VT100\r\n");break;
        default: uart_print("Error- not set\r\n");break;
    }
    uart_print("Current UART line ending: ");
    switch(line){
        case UART_LE_CRONLY: uart_print("CR only\r\n");break;
        case UART_LE_LFONLY: uart_print("LF only\r\n");break;
        case UART_LE_CRLF: uart_print("CR/LF\r\n");break;
        default: uart_print("Error- not set\r\n");break;
    }
    uart_print("Current UART baud rate: ");   
    uart_printl(b);
    uart_print(" baud\r\n");
}