#include "printer.h"

Printer::Printer(){
    position=Point(-1, -1);
    length=0;
    width=0;
    pencount=0;
    port=0;
}

Printer::Printer(long int _length, long int _width, int _pencount, std::map<int, std::string> _pens, int _port, long int _baudrate){
    length=_length;
    width=_width;
    pencount=_pencount;
    pens=_pens;
    port=_port;
    baudrate=_baudrate;
    com=Serial();
}

Point Printer::getPosition(){
    //get head position
    send("M114\n");
    std::string r=recv();
    position=Point(std::stoi(r.substr(r.find("X:")+2, r.find(" ", r.find("X:")))), std::stoi(r.substr(r.find("Y:")+2, r.find(" ", r.find("Y:")))));
    return position;
}

long int Printer::getLength(){
    return length;
}

long int Printer::getWidth(){
    return width;
}

int Printer::getPenCount(){
    return pencount;
}

std::map<int, std::string> Printer::getPens(){
    return pens;
}

bool Printer::getPowerState(){
    return power;
}

std::string Printer::getPort(){
    return "COM"+std::to_string(port);
}

int Printer::getPortInt(){
    return port;
}

long int Printer::getBaudRate(){
    return baudrate;
}

bool Printer::setSettings(long int _length, long int _width, int _pencount, std::map<int, std::string> _pens, int _port, long int _baudrate){
    length=_length;
    width=_width;
    pencount=_pencount;
    pens=_pens;
    port=_port;
    baudrate=_baudrate;
}

bool Printer::setComParameters(int _port, long int _baudrate){
    port=_port;
    baudrate=_baudrate;
}

bool Printer::connect(){
    std::string p="\\\\.\\COM"+std::to_string(port);
    if(!com.conn(p.c_str(), baudrate)){
        return false;
    }

    //get pwr state
    send("M115\n");
    std::string r=recv();
    try{
        nlohmann::json j=nlohmann::json::parse(r);
        power=j["power"];
    }
    catch(nlohmann::json::parse_error &e){
        fprintf(stderr, "ERROR> Can not parse JSON response from printer for M115. Message: %s; position: %i. At: Printer::autoDetect() (file: %s, line: %i)\n", e.what(), e.byte, __FILE__, __LINE__);
        return false;
    }

    //get head position
    getPosition();

    return true;
}

void Printer::disconnect(){
    com.disconn();
}

bool Printer::isConnected(){
    return com.IsConnected();
}

bool Printer::send(std::string s){
    if(!isConnected()){
        return false;
    }
    com.WriteData(s.c_str(), s.size());
    return true;
}

std::string Printer::recv(){
    char buff[501];
    com.ReadData(buff, 500);
    return std::string(buff);
}

bool Printer::autoDetect(){
    if(isConnected()){
        send("M115\n"); //get info from the firmware
        std::string r=recv();
        try{
            nlohmann::json j=nlohmann::json::parse(r);
            length=j["length"];
            width=j["width"];
            pencount=j["pencount"];
            pens.clear();
            for(int i=0; i<pencount; i++){
                pens[i]=j["pens"][i];
            }
        }
        catch(nlohmann::json::parse_error &e){
            fprintf(stderr, "ERROR> Can not parse JSON response from printer for M115. Message: %s; position: %i. At: Printer::autoDetect() (file: %s, line: %i)\n", e.what(), e.byte, __FILE__, __LINE__);
            return false;
        }

        return true;
    }
    return false;
}
