#include "mainwindow.h"
#include "ui_mainwindow.h"




MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    img=NULL;
    pix=NULL;
    part=NULL;
    scene=NULL;
    ui->setupUi(this);
    connect(ui->open,SIGNAL(clicked()),this,SLOT(openFile()));
    connect(ui->close,SIGNAL(clicked()),this,SLOT(closeFile()));
    connect(ui->save,SIGNAL(clicked()),this,SLOT(saveFile()));
    connect(ui->rot,SIGNAL(clicked()),this,SLOT(rotateImg()));
    connect(ui->zoom,SIGNAL(clicked()),this,SLOT(zoomImg()));
    connect(ui->grey,SIGNAL(clicked()),this,SLOT(greyImg()));
    connect(ui->gauss,SIGNAL(clicked()),this,SLOT(gaussImg()));
    connect(ui->sharp,SIGNAL(clicked()),this,SLOT(sharpImg()));
    connect(ui->myFilter,SIGNAL(clicked()),this,SLOT(myFilter()));
    connect(ui->reset,SIGNAL(clicked()),this,SLOT(reset()));
    connect(ui->levelling,SIGNAL(clicked()),this,SLOT(level()));
    connect(ui->levellingCh,SIGNAL(clicked()),this,SLOT(levelCh()));
    connect(ui->medi,SIGNAL(clicked()),this,SLOT(medImg()));
    connect(ui->glass,SIGNAL(clicked()),this,SLOT(glassImg()));
    connect(ui->sharp2,SIGNAL(clicked()),this,SLOT(sharp2Img()));

    ui->filterNum->setMaximum(49);
    ui->filterNum->setMinimum(1);
    ui->filterNum->setValue(3);
    ui->filterNum->setSingleStep(2);
    ui->save->hide();
    ui->close->hide();
}

void MainWindow::showImg(QImage qi)
{

    if (scene!=NULL) delete scene;
    scene= new QGraphicsScene();
    pix->convertFromImage( qi );
    scene->addPixmap(*pix);
    graph->setScene(scene);

}

void MainWindow::openFile(void)
{
     if (img==NULL || graph==NULL ||pix==NULL) closeFile();
     QString fileName = QFileDialog::getOpenFileName(this,
        tr("Open Image"), "C:/", tr("Image Files (*.bmp)"));

     if (fileName.isEmpty()) return;
     ui->save->show();
     ui->close->show();
     ui->open->hide();
     img = new QImage(fileName,"13");
     part = new QImage(*img);
     x0=0; y0=0; x1=img->width()-1; y1=img->height()-1;
     if (img->width()>2048 || img->height()>2048) {closeFile(); return;}


     pix= new QPixmap;
     graph = new MyGV();
     graph->setAlignment(Qt::AlignLeft | Qt::AlignTop);
     connect(graph, SIGNAL(moved(int,int)),this ,SLOT(drawRect(int,int)));
     connect(graph, SIGNAL(closed()),this ,SLOT(closeFile()));
     connect(graph, SIGNAL(released()),this ,SLOT(chosePart()));
     showImg(*img);
      graph->show();
}

void MainWindow::chosePart(void)
{
    if (x0>x1)
    {
        int o=x0;
        x0=x1;
        x1=o;
    }
    if (y0>y1)
    {
        int o=y0;
        y0=y1;
        y1=o;
    }

    *part= QImage(x1-x0+1,y1-y0+1,img->format());
    for (int i= x0; i<=x1;++i)
        for (int j= y0; j<=y1;++j)
            part->setPixel(i-x0,j-y0,img->pixel(i,j));

}

void MainWindow::drawRect(int x, int y)
{
    if (x>img->width()) x=img->width();
    if (x<0) x=0;
    if (y>img->height()) y=img->height();
    if (y<0) y=0;
    if (graph->p0->x()>img->width()) graph->p0->setX(img->width());
    if (graph->p0->x()<0) graph->p0->setX(0);
    if (graph->p0->y()>img->height()) graph->p0->setY(img->height());
    if (graph->p0->y()<0) graph->p0->setY(0);

     QImage im;
     im=img->copy(0,0,img->width(),img->height());

     QPainter paint(&im);
     QPen pen(QColor(50,50,255));
     paint.setPen(pen);
     paint.drawRect(QRect(QPoint(graph->p0->x(),graph->p0->y()),QPoint(x,y)));
     paint.end();

     x0=graph->p0->x();
     y0=graph->p0->y();
     x1=x;
     y1=y;

    showImg(im);


}

void MainWindow::draw()
{
    if (x0==0 && y0==0 && x1==img->width()-1 && y1==img->height()-1) {showImg(*img); return;}

    QImage im;
    im=img->copy(0,0,img->width(),img->height());

    QPainter paint(&im);
    QPen pen(QColor(50,50,255));
    paint.setPen(pen);
    paint.drawRect(QRect(QPoint(x0,y0),QPoint(x1,y1)));
    paint.end();

    showImg(im);

}

void MainWindow::saveFile(void)
{
    if (img==NULL) return;
    QString fileName = QFileDialog::getSaveFileName(this,
               tr("Save Image"), "C:/", tr("Image Files (*.bmp)"));

    if (!(fileName.isEmpty()))
        img->save(fileName,"BMP");

}

void MainWindow::rotateImg(void)
{

    if (img==NULL) return;
    double psi=ui->psi->text().toDouble();


    psi=M_PI * psi / 180;

    *part = rotate(*part,psi);



    buildImage();



    pix->convertFromImage( *img);
    draw();
   // showImg(*img);


}

void MainWindow::zoomImg(void)
{
    if (img==NULL) return;
    double mul=ui->mul->text().toDouble();
    if (mul <= 0) ui->mul->setText("1");
    if (mul>20) ui->mul->setText("1");
    mul=ui->mul->text().toDouble();
    if (mul==1) return;
    *part = zoom(*part,mul);


    if (mul>1)cropImageM(mul);
    else cropImageD(mul);


    pix->convertFromImage( *img);
    draw();
    //showImg(*img);


    *part= QImage(x1-x0+1,y1-y0+1,img->format());
    for (int i= x0; i<=x1;++i)
        for (int j= y0; j<=y1;++j)
            part->setPixel(i-x0,j-y0,img->pixel(i,j));

}

void MainWindow::myFilter(void)
{
d= new Dialog;
    if (img==NULL) return;
    size=ui->filterNum->value();
    for (int i=1;i<=size;i++)
        for (int j=1; j<=size; j++)
        {
            QDoubleSpinBox * b=new QDoubleSpinBox;
            b->setValue(1);
            b->setMinimum(0);

            d->ui->grid->addWidget(b,i,j);

        }
    QPushButton * pb=new QPushButton("Ready");
    connect(pb,SIGNAL(clicked()),this,SLOT(getArray()));
    d->ui->grid->addWidget(pb,0,0);
    d->show();
}

void MainWindow::medImg(void)
{
    if (img==NULL) return;

    *part=median(*part,ui->mediSize->value());
    buildImage();

    draw();



}



void MainWindow::getArray()
{

    for (int i=1;i<=size;i++)
        for (int j=1; j<=size; j++)
        {
           QDoubleSpinBox * sb = qobject_cast<QDoubleSpinBox*>(d->ui->grid->itemAtPosition(i,j)->widget());
           a[i-1][j-1]=sb->value();
        }

    Matrix matr(part,size,a);
    matr.go();
    buildImage();
    draw();
    //delete d;
}

void MainWindow::sharp2Img(void)
{
    if (img==NULL) return;

    a[0][0]=a[2][0]=a[0][2]=a[2][2]=-0.1;
    a[0][1]=a[1][0]=a[1][2]=a[2][1]=-0.2;
    a[1][1]=2.2;
    Matrix matr(part,3,a);
    matr.go();
    buildImage();
    draw();


}


void MainWindow::filtered(void)
{

}

void MainWindow::greyImg(void)
{
     if (img==NULL) return;
     greyWorld(part);
     buildImage();

     draw();
    // ;

}

void MainWindow::gaussImg(void)
{
    if (img==NULL) return;
    if (ui->sgm->text().toDouble() > 5 || ui->sgm->text().toDouble() <=0) ui->sgm->setText("1");
    Gauss g(*part,ui->sgm->text().toDouble());
    *part=g.go();

    buildImage();
    draw();



}

void MainWindow::sharpImg(void)
{
    if (img==NULL) return;

    Gauss g(*part,0.7);
    *part=g.sharp(ui->kSharp->value());
    buildImage();
    draw();


}



void MainWindow::closeFile(void)
{
     if (img!=NULL) delete img;
     if (pix!=NULL) delete pix;
     if (graph!=NULL) delete graph;
     img=NULL; pix=NULL;graph=NULL;
     ui->save->hide();
     ui->close->hide();
     ui->open->show();
}

void MainWindow::buildImage(void)
{

    for (int i= x0; i<=x1;++i)
        for (int j= y0; j<=y1;++j)
           img->setPixel(i,j,part->pixel(i-x0,j-y0));
}

void MainWindow::cropImageM(double mul)
{
    for (int i= x0; i<=x1;++i)
        for (int j= y0; j<=y1;++j)
            img->setPixel(i,j,part->pixel((i-x0)+(x1-x0)*(mul-1)/2,(j-y0)+(y1-y0)*(mul-1)/2));
}

void MainWindow::cropImageD(double mul)
{
    //img->fill(qRgb(0,0,0));
    for (int i= x0; i<=x1;++i)
        for (int j= y0; j<=y1;++j)
        {
            img->setPixel(i-1,j-1,qRgb(0,0,0));
        }

    for (int i= x0; i<=x1;++i)
        for (int j= y0; j<=y1;++j)
        {
            if ((i-x0)+(x1-x0)*(mul-1)/2 < 0 || (j-y0)+(y1-y0)*(mul-1)/2 <0 || (i-x0)+(x1-x0)*(mul-1)/2 >(x1-x0)*mul || (j-y0)+(y1-y0)*(mul-1)/2 >(y1-y0)*mul) continue;
            img->setPixel(i,j,part->pixel((i-x0)+(x1-x0)*(mul-1)/2,(j-y0)+(y1-y0)*(mul-1)/2));
        }

}

void MainWindow::level(void)
{
    if (img==NULL) return;
    * part= levelling(*part);
    buildImage();


    draw();

}

void MainWindow::levelCh(void)
{
    if (img==NULL) return;
    * part= levellingCh(*part);
    buildImage();


    draw();

}

void MainWindow::glassImg(void)
{
    if (img==NULL) return;
    * part= glass(*part,ui->glassSize->value());
    buildImage();


    draw();

}

void MainWindow::reset(void)
{
    if (img==NULL) return;
    showImg(*img);
    x0=y0=0;
    x1=img->width()-1;
    y1=img->height()-1;
    part = new QImage(*img);
}


MainWindow::~MainWindow()
{
    graph->hide();
    this->hide();
    delete ui;
}
