/**
 * /Memory.cpp
 * @version 1.0
 * @desc Body of the memory manager
 * @author Fándly Gergő Zoltán (fandlygergo@gmail.hu, systemtest.tk)
 * @copy 2018 Fándly Gergő Zoltán
 * License:
    Firmware for the Profile F1 fertilizer machine.
    Copyright (C) 2018  Fándly Gergő Zoltán

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 **/

#include "modules.h"

Memory::Memory(){
    //check if everything is set up
    if(EEPROM.read(0)!=170){
        //not set up yet. reset

        //set up to 10101010
        EEPROM.update(0, 170);
        //motor count
        EEPROM.update(1, DEFAULT_MOTOR_COUNT);
        //LCD brightness
        EEPROM.update(2, DEFAULT_LCD_BRIGHTNESS);
        //set everything else to 0
        for(int i=3; i<EEPROM.length(); i++){
            EEPROM.update(i, 0);
        }
    }

    //set timer array to null
    timers=NULL;

    //load timers
    loadTimers();
}

byte Memory::getMotorCount(){
    return EEPROM.read(1);
}

byte Memory::getLCDBrightness(){
    return EEPROM.read(2);
}

byte Memory::getTimerCount(){
    return EEPROM.read(3);
}

Timer Memory::getTimer(byte n){
    return timers[n];
}

byte Memory::getTempCount(){
    return EEPROM.length()-4-(getTimerCount()*8);
}

float Memory::getTemp(byte n){
    byte raw=EEPROM.read(4+(getTimerCount()*8)+n);
    //interval: [-10, 53.75], step: 0.25
    return -10+(0.25*raw);
}

void Memory::setMotorCount(byte a){
    EEPROM.update(1, a);
}

void Memory::setLCDBrightness(byte a){
    EEPROM.update(2, a);
}

void Memory::addTimer(Timer t){
    int mem=4+(getTimerCount()*8);
    EEPROM.update(mem, t.hour);
    EEPROM.update(mem+1, t.minute);
    EEPROM.update(mem+2, t.pump[0]);
    EEPROM.update(mem+3, t.pump[1]);
    EEPROM.update(mem+4, t.pump[2]);
    EEPROM.update(mem+5, t.pump[3]);
    EEPROM.update(mem+6, t.pump[4]);
    EEPROM.update(mem+5, t.switches);
    loadTimers();
}

void Memory::deleteTimer(byte n){
    //shift backwards to its memory address
    for(int i=4+(n*8); i<EEPROM.length()-8; i++){
        EEPROM.update(i, EEPROM.read(i+8));
    }
    //set the remaining to 0
    for(int i=EEPROM.length()-8; i<EEPROM.length(); i++){
        EEPROM.update(i, 0);
    }

    //load timers to RAM
    loadTimers();
}

void Memory::addTemp(float t){
    //FOLI
    //shift all the stuff backwards
    for(int i=4+(getTimerCount()*8); i<EEPROM.length()-1; i++){
        EEPROM.update(i, EEPROM.read(i+1));
    }
    byte data=(t+10)/0.25;
    EEPROM.update(EEPROM.length()-1, data);
}

Timer Memory::getTimer_eeprom(byte n){
    int mem=4+(n*8);
    return Timer(EEPROM.read(mem), EEPROM.read(mem+1), EEPROM.read(mem+2), EEPROM.read(mem+3), EEPROM.read(mem+4), EEPROM.read(mem+5), EEPROM.read(mem+6), EEPROM.read(mem+7));
}

void Memory::loadTimers(){
    int tcount=getTimerCount();
    if(timers!=NULL){
        delete[] timers;
    }
    timers=new Timer[tcount];
    for(int i=0; i<tcount; i++){
        timers[i]=getTimer_eeprom(i);
    }
}
