#include "QMyGraphWidget.h"
#include <QPaintEvent>
#include <QPainter>
#include <QPen>

#include <math.h>

const QPen pens[] = {
    QPen(Qt::blue),
    QPen(Qt::red),
    QPen(Qt::darkGreen),
    QPen(Qt::darkCyan),
    QPen(Qt::darkMagenta),
    QPen(Qt::darkYellow)
};


int QMyGraphWidget::getPosition(double value)
{
   int ret = 0;
   switch(style){
   case linearGraph:
       ret = (maxValue - value) / (maxValue - minValue) * this->height();
       break;
   case logGraph:
       ret = (log(maxValue) - log(value + 1.0e-12)) / (log(maxValue) - log(minValue + 1.0e-12)) * this->height();
       break;
   }
   return ret;
}

void QMyGraphWidget::drawHorizontalLineLog(QPainter *p, QPaintEvent *e)
{
    int x = e->rect().left() + e->rect().left() % 2;
    p->setPen(Qt::black);
    for( ; x <= e->rect().right(); x += 2){
        for(double value = minValue; value < maxValue; value += (maxValue - minValue) / 10.0){
            int y = getPosition(value);
            p->drawPoint(x, y);
        }
    }
}

void QMyGraphWidget::drawHorizontalLineLinear(QPainter *p, QPaintEvent *e)
{
    int x = e->rect().left() + e->rect().left() % 2;
    p->setPen(Qt::black);
    for( ; x <= e->rect().right(); x += 2){
        for(double y = 0; y < height(); y += height() / 10.0){ // うーん
            p->drawPoint(x,(int)y);
        }
    }
}

void QMyGraphWidget::drawGridLine(QPainter *p, QPaintEvent *e)
{
    // 縦線
    p->setPen(Qt::black);
    double x, step;
    step = scale * 50;
    x = (int)(e->rect().left() / step) * step;
    for( ; x <= e->rect().right(); x += step){
        for(int y = 0; y < height(); y += 2){
            p->drawPoint(x, y);
        }
    }
    // 横線は分岐
    switch(style){
    case linearGraph:
        drawHorizontalLineLinear(p, e);
        break;
    case logGraph:
        drawHorizontalLineLog(p, e);
        break;
    }
}

void QMyGraphWidget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);

    painter.setPen(Qt::white);
    painter.setBrush(Qt::white);
    painter.drawRect(e->rect());

    drawGridLine(&painter, e);

    for(unsigned int i = 0; i < graphs.size(); i++){
        painter.setPen(pens[i%6]);
        for(int j = 1; j < graphLength[i]; j++){
            int x1= (j - 1) * scale, x2 = j * scale;
            if(x2 < e->rect().left()){ continue; }
            if(x1 > e->rect().right()){ break; }
            int y1, y2;
            y1 = getPosition((graphs[i])[j-1]);
            y2 = getPosition((graphs[i])[j]);
            painter.drawLine(x1, y1, x2, y2);
        }
    }
}

void QMyGraphWidget::addGraph(double *graph, int length)
{
    if(!graph || length <= 0){ return; }
    graphs.push_back(graph);
    graphLength.push_back(length);
    maxLength = (maxLength < length) ? length : maxLength;
    parent->resize((int)(maxLength * scale), parent->height());
    this->resize((int)(maxLength * scale), this->height());
}

QMyGraphWidget::QMyGraphWidget(QWidget *parent) :
    QWidget(parent)
{
    this->parent = parent;
    destroyGraphs();
}

QMyGraphWidget::~QMyGraphWidget()
{
    destroyGraphs();
}

void QMyGraphWidget::destroyGraphs(void)
{
    graphs.clear();
    graphLength.clear();
    maxLength = 0;
    scale = 1.0;
    minValue = 0.0;
    maxValue = 1.0;
    style = QMyGraphWidget::linearGraph;
}
