#include "setids.h"
#include "ui_setids.h"
#include "object.h"

#include <QMouseEvent>
#include <QPainter>
#include <QInputDialog>

SetIds::SetIds(Sequenz *s, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::SetIds)
{
    ui->setupUi(this);
    this->s = s;
    m = new SetIdsModel();
    m->id = -1;
    SetIdsView *v1 = new SetIdsView( s, m, 0, ui->v1 );
    SetIdsView *v2 = new SetIdsView( s, m, 1, ui->v2 );
    SetIdsView *v3 = new SetIdsView( s, m, 2, ui->v3 );
    SetIdsView *v4 = new SetIdsView( s, m, 3, ui->v4 );
    SetIdsView *v5 = new SetIdsView( s, m, 4, ui->v5 );
    SetIdsView *v6 = new SetIdsView( s, m, 5, ui->v6 );
    SetIdsView *v7 = new SetIdsView( s, m, 6, ui->v7 );
    SetIdsView *v8 = new SetIdsView( s, m, 7, ui->v8 );
    SetIdsView *v9 = new SetIdsView( s, m, 8, ui->v9 );
    views.append( v1 );
    views.append( v2 );
    views.append( v3 );
    views.append( v4 );
    views.append( v5 );
    views.append( v6 );
    views.append( v7 );
    views.append( v8 );
    views.append( v9 );
    m->addView( v1 );
    m->addView( v2 );
    m->addView( v3 );
    m->addView( v4 );
    m->addView( v5 );
    m->addView( v6 );
    m->addView( v7 );
    m->addView( v8 );
    m->addView( v9 );
}

SetIds::~SetIds()
{
    delete ui;
    for( auto i : views )
        delete (SetIdsView*)i;
    delete m;
}

// Die Ids sollen nicht gespeichert werden
void SetIds::on_abbrechen_clicked()
{
    close();
}

// Es sollen weitere Bilder geladen werden
void SetIds::on_weiter_clicked()
{
    int index = m->list.count() - 3;
    if( !s->getFrame( index ) )
        return;
    m->removeViews();
    for( auto i : views )
        delete (SetIdsView*)i;
    views.clear();
    SetIdsView *v1 = new SetIdsView( s, m, index, ui->v1 );
    SetIdsView *v2 = new SetIdsView( s, m, index + 1, ui->v2 );
    SetIdsView *v3 = new SetIdsView( s, m, index + 2, ui->v3 );
    SetIdsView *v4 = new SetIdsView( s, m, index + 3, ui->v4 );
    SetIdsView *v5 = new SetIdsView( s, m, index + 4, ui->v5 );
    SetIdsView *v6 = new SetIdsView( s, m, index + 5, ui->v6 );
    SetIdsView *v7 = new SetIdsView( s, m, index + 6, ui->v7 );
    SetIdsView *v8 = new SetIdsView( s, m, index + 7, ui->v8 );
    SetIdsView *v9 = new SetIdsView( s, m, index + 8, ui->v9 );
    views.append( v1 );
    views.append( v2 );
    views.append( v3 );
    views.append( v4 );
    views.append( v5 );
    views.append( v6 );
    views.append( v7 );
    views.append( v8 );
    views.append( v9 );
    m->addView( v1 );
    m->addView( v2 );
    m->addView( v3 );
    m->addView( v4 );
    m->addView( v5 );
    m->addView( v6 );
    m->addView( v7 );
    m->addView( v8 );
    m->addView( v9 );
}

// Die Ids sollen gespeichert werden
void SetIds::on_speichern_clicked()
{
    int i = 0;
    for( ObjectPolygon p : m->list )
    {
        if( p.isNull() )
        {
            i++;
            continue;
        }
        p->setId( QString::number( m->id ) );
        s->getFrame( i++ )->setNeedSave();
        s->addObjectName( QString::number( m->id ) );
    }
    this->close();
}

// Inhalt der SetIdsView Klasse
//------------------------------

// Transformiert einen Punkt von Bildkoordinaten nach Bildschirmkoordinaten
QPoint SetIdsView::translate(QPoint p)
{
    return QPoint( (int)(p.x() * xScaleFactor), (int)(p.y() * yScaleFactor) );
}

// Transformiert ein Polygon von Bildkoordinaten nach Bildschirmkoordinaten
QPolygon SetIdsView::translatePolygon(QPolygon p)
{
    QPolygon result;
    for( auto point = p.begin(); point != p.end(); point++ )
        result.append( translate( *point ) );
    return result;
}

// Transformiert einen Punkt von Bildschirmkoordinaten nach Bildkoordinaten
QPoint SetIdsView::inverseTranslate(QPoint p)
{
    return QPoint( (int)(p.x() / xScaleFactor), (int)(p.y() / yScaleFactor) );
}

QPointF centerOfPolygon( QPolygon p ); // siehe arbeitsview.cpp

// Zeichnet die View neu
void SetIdsView::paintEvent(QPaintEvent *e)
{
    QPainter painter( this );
    if( f )
    {
        QImage img = f->getImage();
        xScaleFactor = width() / (float)img.width();
        yScaleFactor = height() / (float)img.height();
        // Zeichne Hintergrund Bild
        painter.drawImage( QRect( QPoint( 0, 0 ), translate( QPoint( img.width(), img.height() ) ) ), img );
        QList<ObjectPolygon> objects = f->getObjects();
        QPen white( QColor( 255, 255, 255 ), 2 ); // Erstellt Stifte zum Zeichnen
        QPen white1( QColor( 255, 255, 255 ), 1 );
        QPen lightGreen( QColor( 100, 255, 100 ), 2 );
        QPen green( QColor( 0, 255, 0 ), 2 );
        QPen red( QColor( 255, 0, 0 ), 2 );
        QBrush blackBrush( QColor( 0, 0, 0 ), Qt::SolidPattern );
        for( ObjectPolygon o : objects )
        { // Schleife durch alle Objekte des Bildes
            if( o->isSelected() )
            {
                painter.setPen( white );
                int pIndex;
                if( o == f->getObjectAt( mousePos, pIndex ) )
                    painter.setPen( lightGreen );
                if( ( o->getId() == QString::number( m->id ) || o == m->list.at( i ) ) && m->id != -1 )
                    painter.setPen( green );
                if( o->getId() == QString::number( m->id ) && o != m->list.at( i ) && m->id != -1 )
                    painter.setPen( red );
                pIndex = 0;
                for( QPolygon pol : o->getPolygonList() )
                { // Schleife durch alle Polygone des Bildes
                    QBrush tmpB = painter.brush();
                    painter.drawPolygon( translatePolygon( pol ) ); // Zeichne Polygon
                    QPen tmpPen = painter.pen();
                    painter.setPen( white1 );
                    QFont f = painter.font();
                    f.setPointSize( 12 );
                    QPainterPath tPath;
                    QString id = o->getId();
                    if( o == m->list.at( i ) )
                    {
                        id = QString::number( m->id );
                    }
                    tPath.addText( centerOfPolygon( translatePolygon( pol ) ), f, id );
                    painter.setBrush( blackBrush );
                    painter.drawPath( tPath );
                    painter.setBrush(tmpB);
                    painter.setPen( tmpPen );
                    pIndex++;
                }
            }
        }
        painter.setPen( red );
        if( i - 1 >= 0 && !m->set.at( i ) && !m->list.at( i - 1 ).isNull() )
        {
            QPoint mid = m->list.at( i - 1 )->getBoundingBox().center();
            int index;
            ObjectPolygon p = f->getObjectAt( mid, index );
            if( !p.isNull() )
            {
                m->list.replace( i, p );
                m->notifyViews();
            }
            else
                painter.drawEllipse( translate(mid), 5, 5 );
        }
    }
}

SetIdsView::SetIdsView(Sequenz *s, SetIdsModel *m, int i, QWidget *parent)
    : QWidget( parent )
{
    this->f = s->getFrame( i );
    this->s = s;
    this->m = m;
    this->i = i;
    parent->layout()->addWidget( this );
    this->setMouseTracking( true );
    if( m->list.count() <= i )
    {
        m->list.append( ObjectPolygon() );
        m->set.append( 0 );
    }
}

SetIdsView::~SetIdsView()
{
    ((QWidget*)this->parent())->layout()->removeWidget( this );
}

// Verarbeitet Maus Events und wählt das richtige Objekt aus
void SetIdsView::mouseReleaseEvent(QMouseEvent *e)
{
    if( !f )
        return;
    if( e->button() == Qt::LeftButton )
    { // Wäjlt ein Objekt aus, welches die Id zugewiesen bekommen soll
        int index;
        ObjectPolygon p = f->getObjectAt( mousePos, index );
        if( p.isNull() )
            return;
        if( p->getId() == "-1" && m->id == -1 )
        {
            bool ok;
            int max = s->getMaxObjectId() + 1;
            int id = QInputDialog::getInt( this, "ID", "Gebe die neue ID ein", max, 0, max, 1, &ok );
            if( ok )
            {
                m->id = id;
                m->list.replace( i, p );
                m->set.replace( i, 1 );
            }
        }
        else if( m->id != -1 )
        {
            m->list.replace( i, p );
            m->set.replace( i, 1 );
        }
        else
        {
            m->id = p->getId().toInt();
            m->set.replace( i, 1 );
            m->list.replace( i, p );
        }
    }
    if( e->button() == Qt::RightButton )
    { // Lege Fest, dass für dieses Bild kein Objekt mit der Id versehen werden soll
        m->list.replace( i, ObjectPolygon() );
        m->set.replace( i, 1 );
    }
    m->notifyViews();
}

// Übernimmt die neue Maus Position
void SetIdsView::mouseMoveEvent(QMouseEvent *e)
{
    mousePos = inverseTranslate( e->pos() );
    update();
}