//  Copyright (2013) Cédric Coussinet (cedric.coussinet@nomoseed.net)
//
//  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 <http://www.gnu.org/licenses/>

#include "pointsscatter.h"

#include <QtCore/QFile>
#include <QtCore/QStringList>

static float** data = NULL;
static int lines_nbr;
static int dim_nbr;

static QFile pointsFile;

static QString point;
static QString label;
static QString answer;
static QString dataString;
static QStringList pointString;
static QStringList labelString;
static QStringList clusterString;

static int time_max;
static int time_current;
static int cmp;

static float labelTrace;
static float pointTrace;

void cleanPointsscatterCSV() {
    if (data) {
        for (int i=0; i< lines_nbr; i++)
            free(data[i]);
        free(data);
    }
}

bool initPointsscatterCSV(const QString path){
    lines_nbr = 0;
    time_current = 0;
    cmp = 0;
    pointsFile.setFileName(path);
    pointsFile.open(QIODevice::ReadOnly);
    QString line;
    line = pointsFile.readLine();
    dataString.append(line);
    dim_nbr = line.split(",").size() - 2;
    line = pointsFile.readLine();
    while (line != ""){
        dataString.append(line);
        QStringList items = line.split(",");
        if (items.at(0).toInt() == 1){
            items.removeFirst();
            items.removeFirst();
            pointString.append(items.join(","));
            lines_nbr++;
        }
        else{
            if (items.at(2).toInt() < 0){
                time_current = - items.at(2).toInt();
                cmp++;
                labelString.append(line);
            }
            else if (items.at(0).toInt() == 3)
                clusterString.append(line);
        }
        line = pointsFile.readLine();
    };
    pointsFile.close();
    cmp = cmp % lines_nbr;
    if (!dataString.endsWith("\n"))
        dataString = dataString + "\n";
    data = (float**) malloc(lines_nbr * sizeof(float*));
    for (int i=0; i < lines_nbr; i++)
        data[i] = (float*) malloc(dim_nbr * sizeof(float));
    QStringList vector;
    for (int i=0; i < lines_nbr; i++){
        vector = pointString[i].split(",");
        for (int j=0; j< dim_nbr; j++)
            data[i][j] = vector[j].toFloat();
    }
    time_max = data[lines_nbr-1][0];
    labelTrace = -1;
    pointTrace = -1;
    label = "0";
    return true;
}

void commandPointPointsscatterCSV (const float intensity, const float* cmd){
    answer = QString::number(cmd[0]);
    for (int i = 1; i < dim_nbr - 2; i++)
        answer = answer + "," + QString::number(cmd[i]);
    pointTrace = intensity;
}

void commandLabelPointsscatterCSV (const float intensity, const float* cmd){
    label = QString::number(cmd[0]);
    labelTrace = intensity;
}

float* getDataPointsscatterCSV (){
    cmp = cmp % lines_nbr;
    time_current++;
    if (time_current > time_max)
        time_current = 1;
    if (data[cmp][0] == time_current){
        float* res = data[cmp];
        point = pointString[cmp];
        cmp++;
        return res;
    }
    return NULL;
}

void assumePointsscatterCSV (){
    if (point != ""){
        if (!point.contains(QRegExp ("\n")))
            point = point + "\n";
        if (labelTrace != -1 && pointTrace != -1){
            QStringList temp = point.split(",");
            temp.replace(1,label);
            point = temp.join(",");
            labelString.append("20,1,-" + point);
            if(clusterString.filter("3,5,0," + label).count()>1)
              clusterString.removeOne(clusterString.filter("3,5,0,"+label).first());
            clusterString.append("23,10,-" + point);
            clusterString.append("23,10,0," + label + "," + answer + "\n");
            clusterString.append("1,1,-" + point);
            clusterString.append("20,1,-" + point);
            clusterString.append("3,5,0," + label + "," + answer + "\n");
            pointsFile.open(QIODevice::WriteOnly);
            pointsFile.write((dataString + labelString.join("") + clusterString.join("")).toUtf8().constData());
            labelTrace = -1.0;
            pointTrace = -1.0;
            clusterString.removeAt(clusterString.size() - 2);
            clusterString.removeAt(clusterString.size() - 2);
            clusterString.removeAt(clusterString.size() - 2);
            clusterString.removeAt(clusterString.size() - 2);
            point = "";
        }
        else if (labelTrace != -1) {
            QStringList temp = point.split(",");
            temp.replace(1,label);
            labelString.append("20,1,-" + temp.join(","));
            if(clusterString.filter("3,5,0,"+label).count()>1)
              clusterString.removeOne(clusterString.filter("3,5,0,"+label).first());
            pointsFile.open(QIODevice::WriteOnly);
            pointsFile.write((dataString + labelString.join("") + clusterString.join("")).toUtf8().constData());
            labelTrace = -1.0;
            pointTrace = -1.0;
            clusterString.removeAt(clusterString.size() - 2);
            point = "";
        }
        else if (pointTrace != -1) {
            if(clusterString.filter("3,5,0,"+label).count()>1)
              clusterString.removeOne(clusterString.filter("3,5,0,"+label).first());
            clusterString.append("23,10,-" + point);
            clusterString.append("23,10,0," + label + "," + answer + "\n");
            clusterString.append("1,1,-" + point);
            clusterString.append("3,5,0," + label + "," + answer + "\n");
            pointsFile.open(QIODevice::WriteOnly);
            pointsFile.write((dataString + labelString.join("") + clusterString.join("")).toUtf8().constData());
            labelTrace = -1.0;
            pointTrace = -1.0;
            clusterString.removeAt(clusterString.size() - 2);
            clusterString.removeAt(clusterString.size() - 2);
            clusterString.removeAt(clusterString.size() - 2);
            clusterString.removeAt(clusterString.size() - 2);
            point = "";
        }
        else {
           clusterString.append("23,10,-" + point);
           clusterString.append("1,1,-" + point);
           pointsFile.open(QIODevice::WriteOnly);
           pointsFile.write((dataString + labelString.join("") + clusterString.join("")).toUtf8().constData());
           clusterString.removeLast();
           clusterString.removeLast();
        }
    }
    else{
        pointsFile.open(QIODevice::WriteOnly);
        pointsFile.write((dataString + labelString.join("") + clusterString.join("")).toUtf8().constData());
    }
    pointsFile.close();

}
