#include <QTextStream>
#include <QIODevice>
#include <QtGlobal>
#include <QString>
#include <QFile>
#include <QVariant>
#include <vector>
#include <QColorDialog>
#include <QSvgGenerator>
#include <QGraphicsItem>
#include <QGraphicsLineItem>
#include <QCursor>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mygraphicsview.h"
#include "previewpolyline.h"


// konstruktor
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    input = 0;

    setWindowTitle("Simple SVG Gui (sSVGui)");

//    imageLabel = new QLabel;
//    imageLabel->setBackgroundRole(QPalette::Base);
//    imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
//    imageLabel->setScaledContents(true);


    selected_state = &graphicsScene.selected_state;//?????


    ui->graphicsView->setScene(&graphicsScene);
    ui->graphicsView->show();
    ui->savechanges->setEnabled(selected_state);//?????

    graphicsScene.setSceneRect(0, 0, ui->graphicsView->width(), ui->graphicsView->height());


    ui->widget->setRadiusIsSet(false);

    ui->setdiameter->setChecked(graphicsScene.getSetDiameter());
    ui->setdrawfill->setChecked(graphicsScene.getDrawFill());
    ui->selectcirclefillcolor->setEnabled(graphicsScene.getDrawFill());

    ui->polygonlinewidth->setValue(graphicsScene.getPenWidthPolygon());
    ui->polylinewidth->setValue(graphicsScene.getPenWidthPolyline());
    ui->circlelinewidth->setValue(graphicsScene.getPenWidthCircle());

    ui->diameter->setValue((int)graphicsScene.getDiameter());
    ui->diameter->setEnabled(graphicsScene.getSetDiameter());
    ui->diameterradius->setEnabled(graphicsScene.getSetDiameter());

    QPen pen_polyline;
    pen_polyline.setWidth(graphicsScene.getPenWidthPolyline());
    pen_polyline.setColor(graphicsScene.getColorLine());

    QPen pen_polygon;
    pen_polygon.setWidth(graphicsScene.getPenWidthPolygon());
    pen_polygon.setColor(graphicsScene.getColorPolygonLine());
    QBrush brush;
    brush.setColor(graphicsScene.getColorPolygonFill());
    brush.setStyle(graphicsScene.getStylePolygon());

    QPen pen_circle;
    pen_circle.setWidth(graphicsScene.getPenWidthCircle());
    pen_circle.setColor(graphicsScene.getColorCircleLine());
    QBrush brush_circle;
    brush_circle.setColor(graphicsScene.getColorCircleFill());
    brush_circle.setStyle(graphicsScene.getStyleCircle());

    ui->widget_1->setPen(pen_polyline); // set implicit polyline widget
    ui->widget_2->setPen(pen_polygon); // set implicit polygon widget
    ui->widget_2->setBrush(brush);
    ui->widget->setPen(pen_circle);
    ui->widget->setBrush(brush_circle);

    framewidth = 10;
    ui->framewidth->setValue(framewidth);
    addframe = false;
    ui->addframe->setChecked(addframe);
    ui->framewidth->setEnabled(addframe);


    switch(graphicsScene.getCircleConstructionMethod())
    {
    case 1:
        ui->drawradius->setChecked(true);
        break;
    case 2:
        ui->drawdiameter->setChecked(true);
        break;
    case 3:
        ui->drawthreepoints->setChecked(true);
        break;
    }

    diameterradius = 1; //default - diameter

    width_polygon = graphicsScene.getPenWidthPolygon();
    width_polyline = graphicsScene.getPenWidthPolyline();
    width_circle = graphicsScene.getPenWidthCircle();

    color_polygon_fill = graphicsScene.getColorPolygonFill();
    color_polygon_line = graphicsScene.getColorPolygonLine();
    color_polyline = graphicsScene.getColorLine();
    color_circle_fill = graphicsScene.getColorCircleFill();
    color_circle_line = graphicsScene.getColorCircleLine();

    drawfill = graphicsScene.getDrawFill();
}


// destruktor
MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::mouseMoveEvent(QMouseEvent *e)
{

}


// dvojklik
void MainWindow::mouseDoubleClickEvent(QMouseEvent *e)
{

}


// klik
void MainWindow::mousePressEvent(QMouseEvent *e)
{
    ui->graphicsView->show();
}


// import rastru
void MainWindow::on_actionImport_Image_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Import Image"), QDir::rootPath(),
                                                        tr("All files (*.*);;BMP file (*.bmp);;GIF file (*.gif);;JPG file (*.jpg *.jpeg);;PNG file (*.png)"));

    if(!fileName.isEmpty())
    {
        QImage image(fileName);
        bool notOkay = image.isNull();

        if(notOkay)
        {
            QMessageBox::information(this, tr("sSVGui"), tr("Cannot load %1.").arg(fileName));

            return;
        }

//        size = image.size();

        pixmap = QPixmap::fromImage(image);

        w_pixmap = pixmap.width();
        h_pixmap = pixmap.height();

        graphicsScene.setSceneRect(0, 0, w_pixmap, h_pixmap);
        //graphicsScene.addPixmap(pixmap);
        graphicsScene.setBackgroundBrush(pixmap.scaled(w_pixmap, h_pixmap, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    }
}


// ukonceni programu
void MainWindow::on_actionQuit_triggered()
{
    close();
}


// rezim kresleni polyline
void MainWindow::on_drawPolyline_clicked()
{
    if (!graphicsScene.getActualPolyline().getSize() < 1)
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni mozne opustit neukoncenou polylinii\n"
                                                                 "Ukoncit polylinii?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.closePolyline();
            break;

        case QMessageBox::Cancel:
            ui->drawPolyline->setChecked(true);
            return;
        }
    }

    if (!graphicsScene.getActualPolygon().isEmpty())
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni mozne opustit neuzavreny polygon\n"
                                                                 "Uzavrit polygon?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.closePolygon();
            break;

        case QMessageBox::Cancel:
            ui->drawPolyline->setChecked(false);
            return;
        }
    }

    if (graphicsScene.circleIsComplete() == false)
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni dokoncena kruznice\n"
                                                                 "Zrusit kresleni kruznice?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.cancelCircle();
            break;
        case QMessageBox::Cancel:
            ui->drawPolyline->setChecked(false);
            return;
        }
    }

    if (ui->drawPolyline->isChecked())
    {
        ui->drawCircle->setChecked(false);
        ui->drawPolygon->setChecked(false);
        input = 2;
        graphicsScene.setInput(2);
        ui->graphicsView->viewport()->setCursor(Qt::CrossCursor);
    }
    else
    {
        input = 0;
        graphicsScene.setInput(0);
        ui->graphicsView->viewport()->setCursor(Qt::ArrowCursor);
    }
}


// rezim kresleni polygonu
void MainWindow::on_drawPolygon_clicked()                      
{
    if (!graphicsScene.getActualPolygon().isEmpty())
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni mozne opustit neuzavreny polygon\n"
                                                                 "Uzavrit polygon?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.closePolygon();
            break;

        case QMessageBox::Cancel:
            ui->drawPolygon->setChecked(true);
            return;
        }
    }


    if (!graphicsScene.getActualPolyline().getSize() < 1)
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni mozne opustit neukoncenou polylinii\n"
                                                                 "Ukoncit polylinii?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.closePolyline();
            break;

        case QMessageBox::Cancel:
            ui->drawPolygon->setChecked(false);
            return;
        }
    }


    if (graphicsScene.circleIsComplete() == false)
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni dokoncena kruznice\n"
                                                                 "Zrusit kresleni kruznice?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.cancelCircle();
            break;
        case QMessageBox::Cancel:
            ui->drawPolygon->setChecked(false);
            return;
        }
    }

        if (ui->drawPolygon->isChecked())
    {
        ui->drawCircle->setChecked(false);
        ui->drawPolyline->setChecked(false);
        input = 3;
        graphicsScene.setInput(3);
        //ui->graphicsView->setInput(3);
        ui->graphicsView->viewport()->setCursor(Qt::CrossCursor);
    }
    else
    {
        input = 0;
        graphicsScene.setInput(0);
        //ui->graphicsView->setInput(0);
        ui->graphicsView->viewport()->setCursor(Qt::ArrowCursor);
    }
}


// tlacitko exportu
void MainWindow::on_exportSVG_clicked()
{
    if (graphicsScene.items().size() > 0)
    {
        QString savePath = QFileDialog::getSaveFileName(this, tr("Save SVG"),"",
                                                        tr("SVG files (*.svg)"));

        if (savePath.isEmpty())
            return;

        graphicsScene.setBackgroundBrush(Qt::white);
        graphicsScene.setSceneRect(graphicsScene.itemsBoundingRect());
        QRectF brect = graphicsScene.itemsBoundingRect();

        QSvgGenerator generator;
        generator.setFileName(savePath);
        generator.setTitle("SVG Generator - sSVGui");
        generator.setDescription("An SVG drawing created by the sSVGui");

        if (addframe)
        {
            generator.setSize(QSize(brect.width(),brect.height()));
            generator.setViewBox(QRectF(0-framewidth,0-framewidth,brect.width()+(2*framewidth), brect.height()+(2*framewidth)));
        }
        else
        {
            generator.setSize(QSize(brect.width(),brect.height()));
            generator.setViewBox(QRectF(0,0,brect.width(), brect.height()));
        }

        QPainter painter(&generator);
        graphicsScene.render(&painter);
        graphicsScene.setBackgroundBrush(pixmap.scaled(w_pixmap, h_pixmap, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    }
}


// zmena tloustky obvod. linie polyongu
void MainWindow::on_polygonlinewidth_valueChanged(int value)
{
    graphicsScene.setPenWidthPolygon(value);
    width_polygon = value;

    QPen pen;
    pen.setColor(graphicsScene.getColorPolygonLine());
    pen.setWidth(value);

    ui->widget_2->setPen(pen);
    ui->widget_2->update();

    //    ui->graphicsView->update();
}


// vyber ci zmena barvy vyplne polygonu
void MainWindow::on_polygonfillcolor_clicked()
{
    color_polygon_fill = QColorDialog::getColor(graphicsScene.getColorPolygonFill());
    if (color_polygon_fill.isValid())
        graphicsScene.setColorPolygonFill(color_polygon_fill);

    QBrush brush;
    brush.setColor(color_polygon_fill);
    brush.setStyle(Qt::SolidPattern);

    ui->widget_2->setBrush(brush);

    ui->widget_2->update();

    //    ui->graphicsView->update();
}


// vyber ci zmena barvy obvod. linie polygonu
void MainWindow::on_polygonlinecolor_clicked()
{
    color_polygon_line = QColorDialog::getColor(graphicsScene.getColorPolygonLine());
    if (color_polygon_line.isValid())
        graphicsScene.setColorPolygonLine(color_polygon_line);

    QPen pen;
    pen.setColor(color_polygon_line);
    pen.setWidth(graphicsScene.getPenWidthPolygon());

    ui->widget_2->setPen(pen);
    ui->widget_2->update();

    //    ui->graphicsView->update();
}


// vyber ci zmena barvy polyline
void MainWindow::on_selectLineColor_clicked()
{
    color_polyline = QColorDialog::getColor(graphicsScene.getColorLine());
    if (color_polyline.isValid())
    {
        graphicsScene.setColorLine(color_polyline);
    }

    QPen pen;
    pen.setWidth(graphicsScene.getPenWidthPolyline());
    pen.setColor(color_polyline);

    ui->widget_1->setPen(pen);
    ui->widget_1->update();

    //    ui->graphicsView->update();
}


// zmena tloustky polylinie
void MainWindow::on_polylinewidth_valueChanged(int value)
{
    graphicsScene.setPenWidthLine(value);
    width_polyline = value;

    QPen pen;
    pen.setColor(graphicsScene.getColorLine());
    pen.setWidth(value);

    ui->widget_1->setPen(pen);
    ui->widget_1->update();

    //ui->graphicsView->update();
}


// rezim kresleni kruznice
void MainWindow::on_drawCircle_clicked()
{
    if (!graphicsScene.getActualPolygon().isEmpty())
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni mozne opustit neuzavreny polygon\n"
                                                                 "Uzavrit polygon?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.closePolygon();
            break;

        case QMessageBox::Cancel:
            ui->drawCircle->setChecked(false);
            return;
        }
    }

    if (!graphicsScene.getActualPolyline().getSize() < 1)
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni mozne opustit neukoncenou polylinii\n"
                                                                 "Ukoncit polylinii?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.closePolyline();
            break;

        case QMessageBox::Cancel:
            ui->drawCircle->setChecked(false);
            return;
        }
    }

    if (graphicsScene.circleIsComplete() == false)
    {
        int msgbox = QMessageBox::warning(this, tr("sSVGui"), tr("Neni dokoncena kruznice\n"
                                                                 "Zrusit kresleni kruznice?"),
                                          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);

        switch (msgbox)
        {
        case QMessageBox::Ok:
            graphicsScene.cancelCircle();
            break;
        case QMessageBox::Cancel:
            ui->drawCircle->setChecked(true);
            return;
        }
    }

    if (ui->drawCircle->isChecked())
    {
        ui->drawPolyline->setChecked(false);
        ui->drawPolygon->setChecked(false);
        input = 1;
        graphicsScene.setInput(1);
        ui->graphicsView->viewport()->setCursor(Qt::CrossCursor);
    }
    else
    {
        input = 0;
        graphicsScene.setInput(0);
        ui->graphicsView->viewport()->setCursor(Qt::ArrowCursor);
    }
}


// vypnuti / zapnuti rezimu pevneho prumeru
void MainWindow::on_setdiameter_clicked(bool checked)
{
    graphicsScene.setSetDiameter(checked);
    graphicsScene.setDiameter(ui->diameter->value());
    ui->diameter->setEnabled(checked);
    ui->diameterradius->setEnabled(checked);
    ui->drawdiameter->setEnabled(!checked);
    ui->drawradius->setEnabled(!checked);
    ui->drawthreepoints->setEnabled(!checked);

    ui->widget->setRadiusIsSet(checked);

    if(checked)
    {
        ui->widget->setRadius(graphicsScene.getDiameter()/2);
    }

    ui->widget->update();
}


// zmena tloustky kruznice
void MainWindow::on_circlelinewidth_valueChanged(int value)
{
    graphicsScene.setPenWidthCircle(value);
    width_circle = value;

    QPen pen;
    pen.setColor(graphicsScene.getColorCircleLine());
    pen.setWidth(value);

    ui->widget->setPen(pen);
    ui->widget->update();

    //ui->graphicsView->update();

}


// vyber ci zmena barvy obvodu kruznice
void MainWindow::on_selectcirclelinecolor_clicked()
{
    color_circle_line = QColorDialog::getColor(graphicsScene.getColorCircleLine());
    if (color_circle_line.isValid())
    {
        graphicsScene.setColorCircleLine(color_circle_line);
    }

    QPen pen;
    pen.setWidth(graphicsScene.getPenWidthCircle());
    pen.setColor(color_circle_line);

    ui->widget->setPen(pen);
    ui->widget->update();

    //    ui->graphicsView->update();

}


// vyber ci zmena barvy vyplne kruznice
void MainWindow::on_selectcirclefillcolor_clicked()
{
    color_circle_fill = QColorDialog::getColor(graphicsScene.getColorCircleFill());
    if (color_circle_fill.isValid())
    {
        graphicsScene.setColorCircleFill(color_circle_fill);
    }

    QBrush brush;
    brush.setColor(color_circle_fill);
    brush.setStyle(Qt::SolidPattern);

    ui->widget->setBrush(brush);
    ui->widget->update();
}


// volba - vykresleni vyplne kruznice
void MainWindow::on_setdrawfill_clicked(bool checked)
{
    graphicsScene.setDrawFill(checked);
    drawfill = checked;
    ui->selectcirclefillcolor->setEnabled(checked);

    QBrush brush;
    brush.setColor(graphicsScene.getColorCircleFill());
    brush.setStyle(graphicsScene.getStyleCircle());

    ui->widget->setBrush(brush);
    graphicsScene.update();
    ui->widget->update();
}


// kresleni metodou prumeru
void MainWindow::on_drawdiameter_clicked()
{
    graphicsScene.setCircleConstructMethod(2);
}


// kresleni metodou polomeru
void MainWindow::on_drawradius_clicked()
{
    graphicsScene.setCircleConstructMethod(1);
}


// kresleni metodou tri bodu
void MainWindow::on_drawthreepoints_clicked()
{
    graphicsScene.setCircleConstructMethod(3);
}


// prepinani mezi volbou zadani polomeru nebo prumeru
void MainWindow::on_diameterradius_clicked()
{
    if (diameterradius == 1)
    {
        ui->diameterradius->setText("radius:");
        ui->setdiameter->setText("set radius");
        ui->diameterradius->setToolTip("switch to diameter");
        diameterradius = 2;

        ui->diameter->setValue(graphicsScene.getDiameter()/2);
    }
    else if (diameterradius == 2)
    {
        ui->diameterradius->setText("diameter:");
        ui->setdiameter->setText("set diameter");
        ui->diameterradius->setToolTip("switch to radius");
        diameterradius = 1;

        ui->diameter->setValue(graphicsScene.getDiameter());
    }

    ui->widget->setRadius(graphicsScene.getDiameter()/2);
    ui->widget->update();

}


// nastaveni polomeru/prumeru
void MainWindow::on_diameter_valueChanged(double value)
{
    if (diameterradius == 1)
        graphicsScene.setDiameter(value);
    else if(diameterradius == 2)
        graphicsScene.setDiameter(value*2);

    ui->widget->setRadius(graphicsScene.getDiameter()/2);
    ui->widget->update();
}


// pridani bileho ramecku kolem objektu
void MainWindow::on_addframe_clicked(bool checked)
{
    addframe = checked;
    ui->framewidth->setEnabled(checked);
}


// nastaveni tloustky ramecku
void MainWindow::on_framewidth_valueChanged(double value)
{
    framewidth = value;
}

void MainWindow::on_savechanges_clicked()
{
    QPen pen_polygon;
    pen_polygon.setColor(color_polygon_line);
    pen_polygon.setWidth(width_polygon);

    QBrush brush_polygon;
    brush_polygon.setColor(color_polygon_fill);
    brush_polygon.setStyle(Qt::SolidPattern);

    QPen pen_polyline;
    pen_polyline.setColor(color_polyline);
    pen_polyline.setWidth(width_polyline);

    QPen pen_circle;
    pen_circle.setColor(color_circle_line);
    pen_circle.setWidth(width_circle);

    QBrush brush_circle;
    brush_circle.setColor(color_circle_fill);

    if (drawfill == true)
        brush_circle.setStyle(Qt::SolidPattern);
    else
        brush_circle.setStyle(Qt::NoBrush);

    graphicsScene.saveChanges(brush_polygon, pen_polygon, pen_polyline, pen_circle, brush_circle);
}

void MainWindow::wheelEvent(QWheelEvent *event)
{

}
