#include "config.h"
#include <xc.h>
#include "io.h"
#include "backpack.h"
#include "fonts.h"
#include "util.h"

//see Properties for _XTAL_FREQ (compiler/preprocessing/define macros) _XTAL_FREQ=(32000000UL)
//util.h has most definitions of things used in main

int main(void){
    muteState=storedMuteState;  //load from EEPROM
    masterVol=storedVol;
    lastMasterVol=masterVol;
    ioinit();
    backpackinit();
    backpackclear(BLACK);
    tmr2init();
    IRRXinit();
    backpacksetbuttonobject(&button_up,    85,190,70,40,"UP");
    backpacksetbuttonobject(&button_down,   5,190,70,40,"DOWN");
    backpacksetbuttonobject(&button_mute, 165,190,70,40,"MUTE");
    backpacksetbuttonobject(&button_setup,245,190,70,40,"SETUP");
    backpacksetbuttonobject(&setup_p   ,175,140,40,40,"+");
    backpacksetbuttonobject(&setup_m   ,225,140,40,40,"-");
    backpacksetbuttonobject(&setup_next,275,140,40,40,">");
    backpacksetbuttonobject(&setup_loadir,10,140,150,40,"");     //this doesn't get drawn, but marks an area for touch
    backpackdrawbuttonobject(&button_up,   BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);    
    backpackdrawbuttonobject(&button_down, BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);    
    backpackdrawbuttonobject(&button_mute, BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);    
    backpackdrawbuttonobject(&button_setup,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);        
    drawbitmapmonoRLE4(10,7,SClogoRLE4,ORANGE,BLACK);
    backpackchararrayfont(310-72,4,"MULTI-",YELLOW,BLACK,arial_bold12x16);
    backpackchararrayfont(310-84,24,"CHANNEL",YELLOW,BLACK,arial_bold12x16);
    backpackchararrayfont(310-168,44,"VOLUME CONTROL",YELLOW,BLACK,arial_bold12x16);    
    latbits.SHDN_DP=0;      //turn off
    if(lastMuteState!=muteState){       //unmute on boot if needed
        changeMute(muteState);
        lastMuteState=muteState;
    }   
    updateFlag=1;   //redraw
    backpackcharfontRLE(138,70,CHAR_POINT,BUTTON_FORE,BUTTON_BACK,Arial88);
    backpackcharfontRLE(226,70,CHAR_d,BUTTON_FORE,BUTTON_BACK,Arial88);
    backpackcharfontRLE(270,70,CHAR_B,BUTTON_FORE,BUTTON_BACK,Arial88);
    editSetup(0);       //check EEPROM config
    GIE=1;
    while (1) {        
        backpackbuttonupdate(&button_up);
        backpackbuttonupdate(&button_down);
        backpackbuttonupdate(&button_mute);
        backpackbuttonupdate(&button_setup);
        if(button_up.p){
            masterVol=masterVol+5;
            updateFlag=1;
        }
        if(button_down.p){
            masterVol=masterVol-5;
            updateFlag=1;
        }
        if(backpackbuttowndownevent(&button_mute)){ //toggle
            if(muteState){muteState=0;}else{muteState=1;}
        }
        if(backpackbuttowndownevent(&button_setup)){      //toggle off if set
            if(doSetup){doSetup=0;setupIndex=0;}
        }
        if(button_setup.p){
            if(setupCtr==0){doSetup=1;} //has been held in for enough delay
        }else{
            setupCtr=SETUP_TIME;
        }
        //these are conditional on change
        backpackdrawbuttonobject(&button_up,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);          
        backpackdrawbuttonobject(&button_down,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);          
        backpackdrawbuttonobject(&button_mute,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);          
        backpackdrawbuttonobject(&button_setup,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);          
        //check setup buttons and redraw
        if(doSetup){
            backpackbuttonupdate(&setup_p);
            backpackbuttonupdate(&setup_m);
            backpackbuttonupdate(&setup_next);
            if(setup_p.p){  //repeat action
                editSetup(1);
                updateFlag=1;
            }
            if(setup_m.p){  //repeat action
                editSetup(-1);                
                updateFlag=1;
            }    
            if(backpackbuttowndownevent(&setup_next)){ //single action
                setupIndex++;
                if(setupIndex>=SETUP_COUNT){setupIndex=0;} 
                if(setupIndex>=(cur.d.chansInUse+8)){setupIndex=0;} 
                updateFlag=1;
            }
            backpackdrawbuttonobject(&setup_p,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);        
            backpackdrawbuttonobject(&setup_m,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);        
            backpackdrawbuttonobject(&setup_next,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);                                
        }
        if(slaveIN){
            if(slaveIN==SW_FLAG_VALUE){     //toggle mute received from slave
                if(muteState){muteState=0;}else{muteState=1;}
                updateFlag=1;
            }else if((slaveIN>64)&&(slaveIN<192)){
                masterVol=masterVol+(slaveIN-128)*5;
                updateFlag=1;
            }            
            slaveIN=0;      //processed
        }
        if(IRready){
            if(IRadd==cur.d.IRdevice){
                codeSeen=1;
                IRrpt=0; //avoid immediate repeats causing skidding
                if(IRcode==cur.d.IRdownButton){
                    masterVol=masterVol-5;
                    updateFlag=1;
                }
                else if(IRcode==cur.d.IRupButton){
                    masterVol=masterVol+5;
                    updateFlag=1;
                }
                else if(IRcode==cur.d.IRmuteButton){
                    if(muteState){muteState=0;}else{muteState=1;}
                    IRready=0;  //we don't want repeats on mute
                }else{
                    IRready=0; //clear any unwanted codes
                }                
            }else{
                IRready=0; //clear any unwanted codes
            }
        }
        //handle any overflow
        if(masterVol<MASTER_MIN){masterVol=MASTER_MIN;}
        if(masterVol>cur.d.volMax*10){masterVol=cur.d.volMax*10;}        
        if(lastMuteState!=muteState){//mute ramping logic
            flagSaveNeeded();
            updateFlag=1;
            changeMute(muteState);
            lastMuteState=muteState;
        }
        if(lastMasterVol!=masterVol){
            lastMasterVol=masterVol;
            flagSaveNeeded();
        }        
        if((saveCounter==0)&&(saveDone==0)){
            saveDone=1;
            saveToEEPROM();
            updateFlag=1;
        }
        if(doSetup!=lastSetup){updateFlag=1;}
        if(cur.d.slaveInUse){
            if(muteState){
                slaveIN=sendSlave(0);
            }else{
                slaveIN=sendSlave(((masterVol/5)+128)&0xFF);            
            }
        }
        if(updateFlag==1){
            updateFlag=0;
            if(doSetup!=lastSetup){
                lastSetup=doSetup;
                backpackbox(0,130,319,189,BLACK);   //clear area
                if(doSetup){
                    backpackchararrayfont(50,163,"(   ..   )",WHITE,BLACK,arial_bold12x16);            
                    backpackbuttonrefresh(&setup_p);
                    backpackbuttonrefresh(&setup_m);
                    backpackbuttonrefresh(&setup_next);
                    backpackdrawbuttonobject(&setup_p,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);        
                    backpackdrawbuttonobject(&setup_m,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);        
                    backpackdrawbuttonobject(&setup_next,BUTTON_FORE,BUTTON_BACK,BUTTON_FONT);                        
                }   //no else as MUTE/EEPROM get fully redrawn every time
            }
            if(doSetup){
                backpackchararrayfont(10,143,setupNames[setupIndex],WHITE,BLACK,arial_bold12x16);            
                showN(cur.e[setupIndex],2,163);
                if(setupIndex>=4){
                    showN(setupMin[setupIndex],62,163);
                    showN(setupMax[setupIndex],122,163);
                }
            }else{
                if(saveDone){colourSelect=GREY;}else{colourSelect=YELLOW;}
                backpackchararrayfont(44,153,"EEPROM",colourSelect,BLACK,arial_bold12x16);            
                if(muteState){
                    drawbitmapmonoRLE4(156,144,MUTEoniconRLE4,GREEN,BLACK);
                }else{
                    drawbitmapmonoRLE4(156,144,MUTEofficonRLE4,GREY,BLACK);
                }
            }
            if(muteState){colourSelect=GREY;}else{colourSelect=WHITE;}
            //digipotVol=cur.d.vol_0+(int)(((long)masterVol*cur.d.vol_m)/256);
            digipotVol=getStep(masterVol-(cur.d.dbOffset*10));
            setDPchannels(digipotVol,(unsigned char)cur.d.chansInUse);   //this handles clamping/clipping
            getDigits((unsigned int)abs(masterVol),digits); //abs returns an int!
            xx=6;
            if(digits[2]==0){
                xx=xx+backpackcharfontRLE(xx,70,CHAR_SPACE,colourSelect,BUTTON_BACK,Arial88);            
            }
            if(masterVol<0){
                xx=xx+backpackcharfontRLE(xx,70,CHAR_MINUS,colourSelect,BUTTON_BACK,Arial88);
            }else{
                xx=xx+backpackcharfontRLE(xx,70,CHAR_SPACE,colourSelect,BUTTON_BACK,Arial88);            
            }
            if(digits[2]!=0){
                xx=xx+backpackcharfontRLE(xx,70,digits[2]+'0',colourSelect,BUTTON_BACK,Arial88);            
            }
            backpackcharfontRLE( 94,70,digits[3]+'0',colourSelect,BUTTON_BACK,Arial88);
            backpackcharfontRLE(182,70,digits[4]+'0',colourSelect,BUTTON_BACK,Arial88);
            if(codeSeen){       //do this after redraw to allow repeats to be seen
                if(IRrpt==0){IRready=0;}    //don't clear if repeat
                IRrpt=0;        //this will be set in next loop if a repeat is seen
                codeSeen=0;
            }
/*
//debugging display
        showN(masterVol,0,0);
        showN(digipotVol,0,20);
        showN(dpSteps[digipotVol],0,40);
*/
        }else{
            if(slaveIN==0){delay(20);}      //avoid very fast updates if nothing needs to be done
        }
        if(doSetup && (setupIndex<4)){
            if(backpackbuttonobjecttouched(&setup_loadir) || backpackbuttonobjecttouchedinv(&setup_loadir)){
                if(setupIndex==0){cur.d.IRdevice=IRadd;}
                else if(setupIndex==1){cur.d.IRdownButton=IRcode;}
                else if(setupIndex==2){cur.d.IRupButton=IRcode;}
                else if(setupIndex==3){cur.d.IRmuteButton=IRcode;}
                updateFlag=1;
            }
            showN(IRadd,62,163);
            showN(IRcode,122,163);                                
        }
        if(portbits.IRRX_PIN==0){irTelltale=IR_TELLTAME_TIME;} //to give some persistence of vision
        if(irTelltale){            
            backpackcharfont(193,14,'O',RED,BUTTON_BACK,arial_bold12x16);            
        }else{
            backpackcharfont(193,14,' ',RED,BUTTON_BACK,arial_bold12x16);            
        }
    }
}
