/**
 * @author Rémi Heredero (remi@heredero.ch)
 * @version. 0.0.6
 * @date 2023-06-15
 */
#include "factory.h"


//the factory object containing all objects of our system
static Factory theFactory;


//all the getters
LED* l1() {
    return &theFactory.l1_;
}
LED* l2()  {
    return &theFactory.l2_;
}
LED* l3()  {
    return &theFactory.l3_;
}
LED* l4()  {
    return &theFactory.l4_;
}
LED* l5()  {
    return &theFactory.l5_;
}
LED* l6()  {
    return &theFactory.l6_;
}
LED* l7()  {
    return &theFactory.l7_;
}
LED* l8()  {
    return &theFactory.l8_;
}
LED* l9()  {
    return &theFactory.l9_;
}
LED* l10()  {
    return &theFactory.l10_;
}

BUTTON* b1() {
    return &theFactory.b1_;
}
BUTTON* b2() {
    return &theFactory.b2_;
}
BUTTON* b3() {
    return &theFactory.b3_;
}

CLICK_HANDLER* ch1() {
    return &theFactory.ch1_;
}
CLICK_HANDLER* ch2() {
    return &theFactory.ch2_;
}
CLICK_HANDLER* ch3() {
    return &theFactory.ch3_;
}

BLINKER* blL() {
    return &theFactory.blL_;
}
BLINKER* blR() {
    return &theFactory.blR_;
}
BLINKER* blB() {
    return &theFactory.blB_;
}

APP* app() {
    return &theFactory.app_;
}

//initialize all objects
void Factory_init() {
    LED_init(l1(), 1);
    LED_init(l2(), 2);
    LED_init(l3(), 3);
    LED_init(l4(), 4);
    LED_init(l5(), 5);
    LED_init(l6(), 6);
    LED_init(l7(), 7);
    LED_init(l8(), 8);
    LED_init(l9(), 9);
    LED_init(l10(), 10);
    
    LED_initHW(l1());
    LED_initHW(l2());
    LED_initHW(l3());
    LED_initHW(l4());
    LED_initHW(l5());
    LED_initHW(l6());
    LED_initHW(l7());
    LED_initHW(l8());
    LED_initHW(l9());
    LED_initHW(l10());
    
    
    BUTTON_init(b1(), 1);
    BUTTON_init(b2(), 2);
    BUTTON_init(b3(), 3);
    
    BUTTON_initHW(b1());
    BUTTON_initHW(b2());
    BUTTON_initHW(b3());
    
    CLICK_HANDLER_init(ch1(), b1());
    CLICK_HANDLER_init(ch2(), b2());
    CLICK_HANDLER_init(ch3(), b3());
    
    BLINKER_init(blL());
    BLINKER_init(blR());
    BLINKER_init(blB());
    
    APP_init(app());
    
}

void warningBlink(void* on_){
    bool on = (bool)on_;
    BLINKER_endBlink(blL());
    BLINKER_endBlink(blR());
    if(on) {
        LED_on(l1());
        LED_on(l10());
    } else {
        LED_off(l1());
        LED_off(l10());
    }
}

//connect objects if required
void Factory_build() {
    
    BLINKER_setTurnOn(blL(), BLINKER_defineCallBack(&LED_on, l1()));
    BLINKER_setTurnOff(blL(), BLINKER_defineCallBack(&LED_off, l1()));
    BLINKER_setTurnOn(blR(), BLINKER_defineCallBack(&LED_on, l10()));
    BLINKER_setTurnOff(blR(), BLINKER_defineCallBack(&LED_off, l10()));
    BLINKER_setTurnOn(blB(), BLINKER_defineCallBack(&warningBlink, true));
    BLINKER_setTurnOff(blB(), BLINKER_defineCallBack(&warningBlink, false));
    
}

//start all state machines
void Factory_start() {
    BUTTON_startBehaviour(b1());
    BUTTON_startBehaviour(b2());
    BUTTON_startBehaviour(b3());
    CLICK_HANDLER_startBehaviour(ch1());
    CLICK_HANDLER_startBehaviour(ch2());
    CLICK_HANDLER_startBehaviour(ch3());
    BLINKER_starBehaviour(blL());
    BLINKER_starBehaviour(blR());
    BLINKER_starBehaviour(blB());
    APP_startBehaviour(app());
}
