#include "panel.h"
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

#include "pcd8544.h"
#include "timelib.h"
#include "fat.h"
#include "main.h"
#include "twi_lib.h"
#include "fat_config.h"
#include "partition.h"
#include "sd_raw.h"
#include "sd_raw_config.h"
#include "uart.h"
#include "measuring.h"
#include "adc.h"

unsigned char DirNumFile(sSdCard *fSdCard)
{
    unsigned char Pocet=0;
    unsigned char fPrvniRadek = 1;
    struct fat_dir_entry_struct file_entry;
    while(fat_read_dir((*fSdCard).dd, &file_entry))
    {
        if (!fPrvniRadek)
            Pocet++;
        else
            fPrvniRadek=0;
    }
    return Pocet;
}

void DrawPanel(const sTime fTime)
{
    float baterie = 0;

    //Vykreslení datumu
    LcdGotoXYFont(1,1);
    LcdInt ( FONT_1X, fTime.day);
    LcdChr ( FONT_1X, '.' );
    LcdInt ( FONT_1X, fTime.month);
    LcdChr ( FONT_1X, ' ' );
    LcdInt ( FONT_1X, fTime.hours);
    LcdChr ( FONT_1X, ':' );
    LcdInt ( FONT_1X, fTime.minutes);
    //LcdChr ( FONT_1X, ':' );
    //LcdInt ( FONT_1X, fTime.seconds);

    //vykreslení sd karty
    if (sd_raw_available())
    {
        LcdLine ( 65, 65, 2, 7, 1 );
        LcdLine ( 69, 69, 4, 7, 1 );
        LcdLine ( 66, 67, 2, 2, 1 );
        LcdLine ( 66, 68, 7, 7, 1 );
        LcdPixel( 68, 3, 1 );
    }
    //vykreslení baterie

    LcdLine ( 73, 73, 4, 5, 1 );
    LcdLine ( 74, 74, 2, 7, 1 );
    LcdLine ( 82, 82, 2, 7, 1 );
    LcdLine ( 75, 81, 2, 2, 1 );
    LcdLine ( 75, 81, 7, 7, 1 );

    if (bit_is_set(PINA, PA7))
    {
        ADMUX = 0b01000000;
        ADCSRA |= (1<<ADSC);
        while(ADCSRA & (1 << ADSC));
        baterie = ADC*(33.0 / 1024)-0.25;

        //1
        if (baterie>4.1)
            LcdLine ( 76, 76, 4, 5, 1 );
        //2
        if (baterie>3.9)
        LcdLine ( 78, 78, 4, 5, 1 );
        //3
        if (baterie>3.6)
        LcdLine ( 80, 80, 4, 5, 1 );
    }
    else
    {
        //1
        LcdLine ( 76, 78, 5, 5, 1 );
        //2
        LcdLine ( 78, 78, 4, 5, 1 );
        //3
        LcdLine ( 78, 80, 4, 4, 1 );
    }

}

void DrawMenu(sMenu *fMenu, const sTime fTime, sSdCard *fSdCard)
{
    struct fat_dir_entry_struct file_entry;
    unsigned char fRadkovani = 2;
    unsigned char fPrvniRadek = 1;
    char PomocnyNazev[10];
    PomocnyNazev[0] = 0;
    float vysledek=0;

    DrawPanel(fTime);
    if ( (*fMenu).Uroven == uHlavni)
    {
        if ((*fMenu).Error)
        {
            LcdGotoXYFont(2,2);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("! File error"));
        }
    }

    //vykreslení menu - kouknout na češtinu
    switch ((*fMenu).Uroven)
    {
        case uHlavni:
            LcdGotoXYFont(2,3);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Measurement"));
            LcdGotoXYFont(2,4);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Open"));
            LcdGotoXYFont(2,5);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Setting"));
            LcdSingleBar ( 1, 8*(2+(*fMenu).Radek), 7, 2, 1 );
        break;
        case uNew:


            if ((*fMenu).Radek != 1)
            {
                LcdGotoXYFont(1,3);
                LcdChr(FONT_1X,'<');
            }
            else
                LcdGotoXYFont(2,3);
            switch((*fMenu).Radek)
            {
                case 7:
                        LcdFStr(FONT_1X,(unsigned char*)PSTR(" Current "));
                break;
                case 8:
                        LcdFStr(FONT_1X,(unsigned char*)PSTR(" Resist.[Ohm]"));
                break;
                default:
                        LcdFStr(FONT_1X,(unsigned char*)PSTR(" Voltage "));
                        LcdInt(FONT_1X,(*fMenu).Radek);
                break;
            }

            if ((*fMenu).Radek != (*fMenu).AktualDelka)
            {
                LcdFStr(FONT_1X,(unsigned char*)PSTR(" >"));
            }
            LcdGotoXYFont(1,6);

            //____prepnuti multiplexoru

            PORTC &= ~(_BV( PC3 )) & ~(_BV( PC4 )) & ~(_BV( PC5 ));
            switch((*fMenu).Radek)
            {
                case 1:
                        PORTC |= _BV( PC3 ) | _BV( PC4 ) | _BV( PC5 );
                break;
                case 2:
                        PORTC |= _BV( PC3 ) | _BV( PC4 );
                break;
                case 3:
                        PORTC |= _BV( PC3 ) | _BV( PC5 );
                break;
                case 4:
                        PORTC |= _BV( PC3 );
                break;
                case 5:
                        PORTC |= _BV( PC4 ) | _BV( PC5 );
                break;
                case 6:
                        PORTC |= _BV( PC4 );
                break;
                case 8:
                        PORTC |= _BV( PC5 );
                break;

            }

            switch((*fMenu).Radek)
            {
                case 7:
                        LcdFloat(FONT_2X,GetCurrent());
                        LcdFStr(FONT_2X,(unsigned char*)PSTR(" A"));
                break;
                case 8:
                        LcdFloat(FONT_2X,GetVoltage());
                        /*
                        vysledek = GetResistance();
                        if (vysledek>=1976)
                            LcdFStr(FONT_2X,(unsigned char*)PSTR(" NaN"));
                        else
                            LcdFloat(FONT_2X,GetVoltage());
                        */
                break;
                default:
                        LcdFloat(FONT_2X,GetVoltage());
                        LcdFStr(FONT_2X,(unsigned char*)PSTR(" V"));
                break;
            }

        break;
        case uOpen:
            while(fat_read_dir((*fSdCard).dd, &file_entry))
            {
                if (!fPrvniRadek)
                {
                    if (fRadkovani>(*fMenu).Offset && fRadkovani<=(5+(*fMenu).Offset))
                    {
                        LcdGotoXYFont(2,fRadkovani+1-(*fMenu).Offset);
                        strncat (PomocnyNazev, file_entry.long_name, 10);
                        LcdStr(FONT_1X,PomocnyNazev);
                        PomocnyNazev[0] = 0;
                        LcdChr ( FONT_1X, file_entry.attributes & FAT_ATTRIB_DIR ? '/' : ' ' );
                    }
                    fRadkovani++;
                }
                else
                    fPrvniRadek=0;
            }
            //(*fMenu).AktualDelka = fRadkovani-2;
            LcdSingleBar ( 1, 8*(2+(*fMenu).Radek-(*fMenu).Offset), 7, 2, 1 );
        break;
        case uSetting:
            LcdGotoXYFont(2,3);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Contrast"));
            if ((*fMenu).Orientation == Horizontal && (*fMenu).Radek == rContrast)
                LcdFStr(FONT_1X,(unsigned char*)PSTR(" <>"));
            LcdGotoXYFont(2,4);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Brightness"));
            if ((*fMenu).Orientation == Horizontal && (*fMenu).Radek == rBrightness)
                LcdFStr(FONT_1X,(unsigned char*)PSTR(" <>"));
            LcdGotoXYFont(2,5);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Time/Date"));
            LcdSingleBar ( 1, 8*(2+(*fMenu).Radek), 7, 2, 1 );
        break;

        case uSetTime:
            LcdGotoXYFont(2,3);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Time:"));
            LcdGotoXYFont(3,4);

            if (fTime.hours < 10)
                LcdChr( FONT_1X, '0');
            LcdInt ( FONT_1X, fTime.hours);
            LcdChr ( FONT_1X, ':' );

            if (fTime.minutes < 10)
                LcdChr( FONT_1X, '0');
            LcdInt ( FONT_1X, fTime.minutes);
            LcdChr ( FONT_1X, ':' );

            if (fTime.seconds < 10)
                LcdChr( FONT_1X, '0');
            LcdInt ( FONT_1X, fTime.seconds);
            LcdGotoXYFont(2,5);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Date:"));
            LcdGotoXYFont(3,6);

            if (fTime.day < 10)
                LcdChr( FONT_1X, '0');
            LcdInt ( FONT_1X, fTime.day);
            LcdChr ( FONT_1X, '.' );

            if (fTime.month < 10)
                LcdChr( FONT_1X, '0');
            LcdInt ( FONT_1X, fTime.month);
            LcdChr ( FONT_1X, ' ' );

            LcdFStr(FONT_1X,(unsigned char*)PSTR("20"));
            if (fTime.year < 10)
                LcdChr( FONT_1X, '0');
            LcdInt ( FONT_1X, fTime.year);
            fRadkovani = 0;
            fPrvniRadek = 0;
            switch ((*fMenu).Radek) {
                case 1:
                    LcdRect ( 11 , 24 , 24, 33, PIXEL_XOR );
                break;
                case 2:
                    LcdRect ( 29, 42 , 24, 33, PIXEL_XOR );
                break;
                case 3:
                    LcdRect ( 47, 60 , 24, 33, PIXEL_XOR );
                break;
                case 4:
                    LcdRect ( 11 , 24 , 40, 48, PIXEL_XOR );
                break;
                case 5:
                    LcdRect ( 29, 42 , 40, 48, PIXEL_XOR );
                break;
                case 6:
                    LcdRect ( 47, 72 , 40, 48, PIXEL_XOR );
                break;
            }
        break;
        case uMeasuring:

            LcdGotoXYFont(2,3);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Measuring "));
            if ((*fMenu).Radek>=2)
            {
               (*fMenu).Radek = 0;
               LcdFStr(FONT_1X,(unsigned char*)PSTR("..."));
            }
            else
                (*fMenu).Radek+=1;
            LcdGotoXYFont(1,6);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Stop"));
            LcdGotoXYFont(10,6);
            LcdFStr(FONT_1X,(unsigned char*)PSTR("Sleep"));
        break;
    }

}
unsigned char PanelLoop(sMenu *fMenu, sSdCard *fSdCard, sMeasuring *fMeasuring)
{
    unsigned char fRadkovani = 1;
    unsigned char navrat = 0;
    struct fat_dir_entry_struct file_entry;
    if ((*fMenu).Uroven == 1)
        (*fMenu).AktualDelka = 3;
    if (bit_is_clear(KlavPIN, KlavUp))
    {
            _delay_ms(TlacPause);
            if (bit_is_clear(KlavPIN, KlavUp))
            {
                if ((*fMenu).Radek!=1 && (*fMenu).Orientation == Vertical)
                {
                    (*fMenu).Radek-=1;
                    if ((*fMenu).Uroven == uOpen && ((*fMenu).Radek)==((*fMenu).Offset)-1)
                        (*fMenu).Offset -=1;
                }
                if ((*fMenu).Uroven == uSetTime)
                    SetTime((*fMenu).Radek, 1);

                navrat = 1;
            }

    }
    if (bit_is_clear(KlavPIN, KlavDow))
    {
            _delay_ms(TlacPause);
            if (bit_is_clear(KlavPIN, KlavDow))
            {

                    if (((*fMenu).Radek)!=((*fMenu).AktualDelka) && (*fMenu).Orientation == Vertical)
                    {
                        (*fMenu).Radek+=1;
                        if ((*fMenu).Uroven == uOpen && ((*fMenu).Radek)>=6)
                            (*fMenu).Offset +=1;

                    }
                    if ((*fMenu).Uroven == uSetTime)
                        SetTime((*fMenu).Radek, 0);
                navrat = 1;
            }
    }
    if (bit_is_clear(KlavPIN, KlavOk))
    {
            _delay_ms(TlacPause);
            if (bit_is_clear(KlavPIN, KlavOk))
            {
                navrat = 1;
                switch ((*fMenu).Uroven)
                {
                    case uHlavni:
                        switch ((*fMenu).Radek)
                        {
                            case rNew:
                                (*fMenu).Uroven = uNew;
                                (*fMenu).Radek = 1;
                                (*fMenu).AktualDelka = 8;
                                (*fMenu).Orientation = Horizontal;

                            break;
                            case rOpen:
                                (*fMenu).Uroven = uOpen;
                                (*fMenu).Radek = 1;
                                (*fMenu).AktualDelka = DirNumFile(fSdCard);
                                (*fMenu).Offset = 1;
                                (*fMenu).Bottom = 5;
                            break;
                            case rSetting:
                                (*fMenu).Uroven = uSetting;
                                (*fMenu).Radek = 1;
                                (*fMenu).AktualDelka = 3;
                                _delay_ms(100);     //pauza kvůli dlouhemu drzeni ok tlacitka a naslednemu zacykleni
                            break;
                        }
                    break;
                    case uSetting:
                        switch ((*fMenu).Radek)
                        {
                            case rSetTime:
                                (*fMenu).Uroven = 5;
                                (*fMenu).Radek = 1;
                                (*fMenu).AktualDelka = 6;
                                (*fMenu).Orientation = Horizontal;
                            break;
                            case rContrast:
                                if ((*fMenu).Orientation == Horizontal)
                                {
                                    (*fMenu).Orientation = Vertical;
                                    eeprom_write_byte((uint8_t*)1,(*fMenu).Contrast);
                                }
                                else
                                    (*fMenu).Orientation = Horizontal;
                                _delay_ms(100);     //pauza kvůli dlouhemu drzeni ok tlacitka a naslednemu zacykleni

                            break;
                            case rBrightness:
                                if ((*fMenu).Orientation == Horizontal)
                                {
                                    (*fMenu).Orientation = Vertical;
                                    eeprom_write_byte((uint8_t*)2,(*fMenu).Brightness);
                                }
                                else
                                    (*fMenu).Orientation = Horizontal;
                                _delay_ms(100);     //pauza kvůli dlouhemu drzeni ok tlacitka a naslednemu zacykleni
                            break;
                        }
                    break;
                    case uSetTime:
                        (*fMenu).Uroven = uSetting;
                        (*fMenu).Radek = 3;
                        (*fMenu).AktualDelka = 3;
                        (*fMenu).Orientation = Vertical;
                        _delay_ms(100);     //pauza kvůli dlouhemu drzeni ok tlacitka a naslednemu zacykleni
                    break;
                    case uNew:
                        (*fMenu).Uroven = uHlavni;
                        (*fMenu).Radek = 1;
                        (*fMenu).AktualDelka = 3;
                        (*fMenu).Orientation = Vertical;
                        _delay_ms(100);     //pauza kvůli dlouhemu drzeni ok tlacitka a naslednemu zacykleni
                    break;
                    case uOpen:

                        while(fat_read_dir((*fSdCard).dd, &file_entry))
                        {
                            if (fRadkovani == (*fMenu).Radek+1 && file_entry.attributes == FAT_ATTRIB_DIR)
                            {
                                    struct fat_dir_struct* dd_new = fat_open_dir((*fSdCard).fs, &file_entry);
                                    if(dd_new)
                                    {
                                        fat_close_dir((*fSdCard).dd);
                                        (*fSdCard).dd = dd_new;
                                        (*fMenu).Radek = 1;     //-----------tohle změnit v případě stejné položky u navratu o složku z5
                                        (*fMenu).Offset = 1;     //-----------tohle změnit v případě stejné položky u navratu o složku z5
                                        (*fMenu).AktualDelka = DirNumFile(fSdCard);
                                    }
                                    break;
                            }
                            if (fRadkovani == (*fMenu).Radek+1 && strstr(file_entry.long_name,".dcfg"))
                            {

                                (*fMeasuring).File = fat_open_file((*fSdCard).fs, &file_entry);
                               if((*fMeasuring).File)
                               {
                                   (*fMenu).Uroven = uMeasuring;
                                   (*fMenu).Radek = 1;
                                   (*fMeasuring).Init = 1;
                               }
                               else
                                   //Výpis chyby neotevření souboru
                                   uart_puts_p(PSTR("Soubor nelze otevrit\n"));


                            }
                            fRadkovani++;
                        }



                    break;

                }
            }
    }
    if (bit_is_clear(KlavPIN, KlavRig))
    {
            _delay_ms(TlacPause);
            if (bit_is_clear(KlavPIN, KlavRig))
            {
                if ((*fMenu).Radek!=(*fMenu).AktualDelka && (*fMenu).Orientation == Horizontal && (*fMenu).Uroven != uSetting)
                    (*fMenu).Radek+=1;
                if ((*fMenu).Uroven == uSetting && (*fMenu).Radek== rContrast && (*fMenu).Orientation == Horizontal)
                {
                    ((*fMenu).Contrast)+=1;
                    LcdContrast ( (*fMenu).Contrast );

                }
                if ((*fMenu).Uroven == uSetting && (*fMenu).Radek== rBrightness && (*fMenu).Orientation == Horizontal && (*fMenu).Brightness>9)
                {
                    ((*fMenu).Brightness)-=10;
                    OCR2 = ((*fMenu).Brightness);

                }

                navrat = 1;
            }
    }
    if (bit_is_clear(KlavPIN, KlavLef))
    {
            _delay_ms(TlacPause);
            if (bit_is_clear(KlavPIN, KlavLef))
            {
                if ((*fMenu).Radek!=1 && (*fMenu).Orientation == Horizontal  && (*fMenu).Uroven != uSetting)
                    (*fMenu).Radek-=1;
                navrat = 1;
                if (((*fMenu).Uroven == uNew || (*fMenu).Uroven == uOpen || (*fMenu).Uroven == uSetting ) && (*fMenu).Orientation == Vertical)
                {
                    (*fMenu).Radek = (*fMenu).Uroven - 1;
                    (*fMenu).Uroven = uHlavni;
                    (*fMenu).AktualDelka = 3;
                }
                if ((*fMenu).Uroven == uSetting && (*fMenu).Radek== rContrast && (*fMenu).Orientation == Horizontal && (*fMenu).Contrast>0)
                {
                    ((*fMenu).Contrast)-=1;
                    LcdContrast ( (*fMenu).Contrast );

                }
                if ((*fMenu).Uroven == uSetting && (*fMenu).Radek== rBrightness && (*fMenu).Orientation == Horizontal && (*fMenu).Brightness<245)
                {
                    ((*fMenu).Brightness)+=10;
                    OCR2 = ((*fMenu).Brightness);

                }
            }
    }
    return navrat;
}

