#include <app.h>
#include <main.h>
#include <st7735.h>
#include <RotaryCoder.h>
#include <KT0915.h>

/*Arduino APP 未移植 不可用*/
uint8_t app_setup(void){

}
/*
Shows the static content on  display
*/
void showTemplate()
{

    int maxX1 = tft.width() - 2;
    int maxY1 = tft.height() - 5;

    tft.fillScreen(COLOR_BLACK);

    tft.drawRect(2, 2, maxX1, maxY1, COLOR_YELLOW);
    tft.drawLine(2, 40, maxX1, 40, COLOR_YELLOW);
    tft.drawLine(2, 60, maxX1, 60, COLOR_YELLOW);
}

void clearStatus()
{

    char *unit;
    char *bandMode;

    int maxX1 = tft.width() - 6;
    int maxY1 = tft.height() - 6;

    tft.fillRect(3, 3, maxX1, 35, COLOR_BLACK);
    // tft.fillRect(3,61,maxX1, maxY1 - 61, COLOR_BLACK);

    if (band[bandIdx].mode == MODE_FM)
    {
        unit = (char *)"MHz";
        bandMode = (char *)"FM";
    }
    else
    {
        unit = (char *)"KHz";
        bandMode = (char *)"AM";
    }
    tft.setFont(&Serif_plain_7);
    printValue(135, 15, oldMode, bandMode, 7, COLOR_YELLOW);
    printValue(135, 36, oldUnit, unit, 7, COLOR_YELLOW);
}

/*
  Prevents blinking during the frequency display.
  Erases the old digits if it has changed and print the new digit values.
*/
void printValue(int col, int line, char *oldValue, char *newValue, uint8_t space, uint16_t color)
{
    int c = col;
    char *pOld;
    char *pNew;

    pOld = oldValue;
    pNew = newValue;

    // prints just changed digits
    while (*pOld && *pNew)
    {
        if (*pOld != *pNew)
        {
            // Erases olde value
            tft.setTextColor(COLOR_BLACK);
            tft.setCursor(c, line);
            tft.print(*pOld);
            // Writes new value
            tft.setTextColor(color);
            tft.setCursor(c, line);
            tft.print(*pNew);
        }
        pOld++;
        pNew++;
        c += space;
    }

    // Is there anything else to erase?
    tft.setTextColor(COLOR_BLACK);
    while (*pOld)
    {
        tft.setCursor(c, line);
        tft.print(*pOld);
        pOld++;
        c += space;
    }

    // Is there anything else to print?
    tft.setTextColor(color);
    while (*pNew)
    {
        tft.setCursor(c, line);
        tft.print(*pNew);
        pNew++;
        c += space;
    }

    // Save the current content to be tested next time
    strcpy(oldValue, newValue);
}

/*
   Shows frequency information on Display
*/
void showFrequency()
{
    char freq[15];
    char aux[15];

    currentFrequency = rx.getFrequency();

    // Serial.println(currentFrequency);

    tft.setFont(&DSEG7_Classic_Mini_Regular_30);
    tft.setTextSize(1);

    if (band[bandIdx].mode == MODE_FM) // FM
    {
        sprintf(aux, "%6.6lu", currentFrequency);
        freq[0] = aux[0];
        freq[1] = aux[1];
        freq[2] = aux[2];
        freq[3] = '\0';
        freq[4] = aux[3];
        freq[5] = aux[4];
        freq[6] = '\0';

        printValue(2, 36, &oldFreq[0], &freq[0], 23, COLOR_RED);
        printValue(82, 36, &oldFreq[4], &freq[4], 23, COLOR_RED);
        tft.setCursor(80, 35);
        tft.print('.');
    }
    else // AM
    {
        sprintf(aux, "%5lu", currentFrequency);
        freq[0] = aux[0];
        freq[1] = aux[1];
        freq[2] = aux[2];
        freq[3] = aux[3];
        freq[4] = aux[4];
        freq[5] = '\0';
        printValue(2, 36, &oldFreq[0], &freq[0], 23, COLOR_RED);
    }
}

/*
    Show some basic information on display
*/
void showStatus()
{
    resetBuffer();
    clearStatus();
    showFrequency();
    showVolume();
    showBandwidth();
}

/* *******************************
   Shows RSSI status
*/
void showRSSI()
{
    /*
    char rssi[15];

    // Check AM or FM
    sprintf(rssi, "%3.3udBuV", (band[bandIdx].mode ==  MODE_FM)? rx.getFmRssi():rx.getAmRssi());
    tft.setFont(&Serif_plain_14);
    tft.setTextSize(1);
    printValue(5, 55, oldRssi, rssi, 11, COLOR_WHITE);
    */
}

void showBandwidth()
{
    char sBw[15];

    if (band[bandIdx].mode != MODE_AM)
        return;

    sprintf(sBw, "%cKHz", am_bw[bwIdx]);

    tft.setFont(&Serif_plain_14);
    tft.setTextSize(1);
    printValue(5, 80, oldBW, sBw, 11, COLOR_WHITE);
}

void showStereo()
{
    // char stereo[10];
    // sprintf(stereo, "%s", (rx.isFmStereo()) ? "St" : "Mo");
    // tft.setFont(&Serif_plain_14);
    // tft.setTextSize(1);
    // printValue(125, 55, oldStereo, stereo, 15, COLOR_WHITE);
}

/*
   Shows the volume level on LCD
*/
void showVolume()
{
    // char sVolume[15];
    // sprintf(sVolume, "Vol: %2.2u", rx.getVolume());
    // printValue(80, 56, oldVolume, sVolume, 6, 1);
}

/*********************************************************

 *********************************************************/

void showSplash()
{
    // Splash
    tft.setFont(&Serif_plain_14);
    tft.setTextSize(1);
    tft.setTextColor(COLOR_YELLOW);
    tft.setCursor(45, 23);
    tft.print("KT0915");
    tft.setCursor(15, 50);
    tft.print("Arduino Library");
    tft.setCursor(25, 80);
    tft.print("By PU2CLR");
    tft.setFont(&Serif_plain_14);
    tft.setTextSize(0);
    tft.setCursor(12, 110);
    tft.print("Ricardo L. Caratti");
    delay(4000);
}

void bandUp()
{
    // save the current frequency for the band
    band[bandIdx].default_frequency = currentFrequency;

    if (bandIdx < lastBand)
    {
        bandIdx++;
    }
    else
    {
        bandIdx = 0;
    }
    useBand();
}

void bandDown()
{
    // save the current frequency for the band
    band[bandIdx].default_frequency = currentFrequency;

    if (bandIdx > 0)
    {
        bandIdx--;
    }
    else
    {
        bandIdx = lastBand;
    }
    useBand();
}

void useBand()
{

    if (band[bandIdx].mode == MODE_FM)
    {
        rx.setFM(band[bandIdx].minimum_frequency, band[bandIdx].maximum_frequency, band[bandIdx].default_frequency, band[bandIdx].step);
        rx.setDeEmphasis(DE_EMPHASIS_75);
        // rx.setSoftMute(TURN_OFF);
        rx.setFmAfc(TURN_ON);
        rx.setMono(TURN_OFF); // Force stereo
    }
    else
    {
        rx.setAM(band[bandIdx].minimum_frequency, band[bandIdx].maximum_frequency, band[bandIdx].default_frequency, band[bandIdx].step);
        rx.setAmAfc(TURN_ON);
        rx.setSoftMute(TURN_OFF);
        rx.setAmSpace(0); // Sets Am space channel to 1Khz.
    }
    delay(100);
    currentFrequency = band[bandIdx].default_frequency;
    rx.setFrequency(currentFrequency);
    showStatus();
}

/**
 * Used to test the receiver functions implemented by the library
 */
void doBandwidth()
{
    if (bwIdx == 3)
        bwIdx = 0;
    bwIdx++;
    rx.setAmBandwidth(bwIdx);
    showBandwidth();
    showFrequency();
    delay(300);
}

void doStereo()
{
    rx.setMono((bSt = !bSt));
    bShow = true;
    showStereo();
    delay(100);
}

/**
   Process seek command.
   The seek direction is based on the last encoder direction rotation.
*/
void doSeek()
{
    delay(200);
    bShow = true;
    showFrequency();
}

/*
   Button - Volume control
*/
void volumeButton(byte d)
{

    if (d == 1)
        rx.setVolumeUp();
    else
        rx.setVolumeDown();

    showVolume();
    delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
}

void doFilter()
{
}

void APP_loop()
{

    // Check if the encoder has moved.
    if (encoderCount != 0)
    {
        if (encoderCount == 1)
        {
            rx.setFrequencyUp();
        }
        else
        {
            rx.setFrequencyDown();
        }
        showFrequency();
        bShow = true;
        encoderCount = 0;
    }

    // Check button commands
    if ((millis() - elapsedButton) > MIN_ELAPSED_TIME)
    {
        // check if some button is pressed
        if (digitalRead(BAND_MODE_SWITCH_UP) == LOW)
            bandUp();
        else if (digitalRead(BAND_MODE_SWITCH_DOWN) == LOW)
            bandDown();
        else if (digitalRead(VOL_UP) == LOW)
            volumeButton(1);
        else if (digitalRead(VOL_DOWN) == LOW)
            volumeButton(-1);
        else if (digitalRead(SWITCH_BW) == LOW)
            doBandwidth();
    }

    if ((millis() - pollin_elapsed) > POLLING_TIME)
    {
        showRSSI();
        pollin_elapsed = millis();
    }

    delay(100);
}