#include "mainwindow.h"
#include "ui_mainwindow.h"


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

    //Animation.SetMainWindow(this);

    frameImageDefaultPosX = ui->FrameImage->pos().x();
    frameImageDefaultPosY = ui->FrameImage->pos().y();

    //int sheetDefaultWidth = (ui->SheetWidth->text()).toInt();
    //int sheetDefaultHeight = (ui->SheetHeight->text()).toInt();

    SheetPixmap = boost::shared_ptr<QPixmap>(new QPixmap(4, 4));



}

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


int MainWindow::GetSelectedFrame()
{
    QListWidgetItem * item = *(ui->FrameList->selectedItems().begin());

    int it=0;

    for (int i=0; i<ui->FrameList->count(); i++)
    {
        if (ui->FrameList->item(i) == item)
        {
            it = i;
        }
    }

    return it;
}

void MainWindow::SetAnimation(TAnimation* animation)
{
    Animation = animation;

    QObject::connect(ui->LoadFrameButton, SIGNAL(pressed()), Animation, SLOT(LoadFrame()));
    QObject::connect(ui->FrameList, SIGNAL(itemSelectionChanged()), this, SLOT(ItemClicked()));
    QObject::connect(ui->ShiftX_spinBox, SIGNAL(valueChanged(int)), this, SLOT(ShiftXChanged(int)));
    QObject::connect(ui->ShiftY_spinBox, SIGNAL(valueChanged(int)), this, SLOT(ShiftYChanged(int)));
    QObject::connect(ui->TimeFrameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(TimeFrameChanged(const QString&)));
    QObject::connect(ui->GenerateTimeButton, SIGNAL(pressed()), this, SLOT(GenerateTimeFrameBy12Fps()));
    QObject::connect(ui->GenerateSheetButton, SIGNAL(pressed()), this, SLOT(GenerateSheet()));
    QObject::connect(ui->SaveSheetButton, SIGNAL(pressed()), this, SLOT(SaveSheet()));
    QObject::connect(ui->SaveAnimParamsButton, SIGNAL(pressed()), this, SLOT(SaveAnimationParams()));
    QObject::connect(ui->AnimateCheckBox, SIGNAL(stateChanged(int)), this, SLOT(AnimateCheckBoxStateChanged(int)));
    QObject::connect(ui->ClearButton, SIGNAL(pressed()), this, SLOT(Clear()));

    QObject::connect(&AnimTimer, SIGNAL(timeout()), this, SLOT(TimerTimeout()));




}


void MainWindow::ItemClicked()
{
    SelectFrame(GetSelectedFrame());
}

void MainWindow::ShiftXChanged(int val)
{
    int i = GetSelectedFrame();

    Animation->GetFrame(i).ShiftX = val;

    ItemClicked();
}


void MainWindow::ShiftYChanged(int val)
{
    int i = GetSelectedFrame();

    Animation->GetFrame(i).ShiftY = val;

    ItemClicked();

}

void MainWindow::TimeFrameChanged(const QString& str)
{
    bool ok;

    int timeFrame = str.toInt(&ok);

    if (ok)
    {
        int i = GetSelectedFrame();

        Animation->GetFrame(i).TimeToPlay = timeFrame;
    }
    else
    {
    }
}

void MainWindow::GenerateTimeFrameBy12Fps()
{
    float timeStep = 1000.f / 12.f;

    int frameCount = ui->FrameList->count();

    for (int i=0; i<frameCount; i++)
    {
        int totalTime = static_cast<int>(timeStep * (i + 1));

        Animation->GetFrame(i).TimeToPlay = totalTime;

    }


    ItemClicked();

}


void MainWindow::GenerateSheet()
{
    int sheetWidth = (ui->SheetWidth->text()).toInt();
    int sheetHeight = (ui->SheetHeight->text()).toInt();

    std::vector<TFrameData> frameDataArr;

    SheetPixmap = boost::shared_ptr<QPixmap>(new QPixmap(sheetWidth, sheetHeight));

    QColor transparentColor(0,0,0,0);

    SheetPixmap->fill(transparentColor);

    Animation->FillSheet(SheetPixmap, frameDataArr);

    ui->PixmapSheet->setPixmap(*SheetPixmap);





    ui->OutputXmlFile->clear();

    AnimationParamsText = "<Animation>\n\t<Frames>\n";

    for (size_t i = 0; i < frameDataArr.size(); i++)
    {
        AnimationParamsText += QString("\t\t<Frame><TexCoordFrom x='%1' y='%2'/><TexCoordTo x='%3' y='%4'/><TimePassed>%5</TimePassed></Frame>\n")
                .arg(QString::number(frameDataArr[i].TexCoordFromX))
                .arg(QString::number(frameDataArr[i].TexCoordFromY))
                .arg(QString::number(frameDataArr[i].TexCoordToX))
                .arg(QString::number(frameDataArr[i].TexCoordToY))
                .arg(QString::number(frameDataArr[i].TimeToPlay));
    }

    AnimationParamsText += "\t</Frames>\n</Animation>";
    ui->OutputXmlFile->appendPlainText(AnimationParamsText);

}

void MainWindow::SaveSheet()
{
    QFileDialog dialog(this);

    dialog.setAcceptMode(QFileDialog::AcceptSave);

    dialog.setFileMode(QFileDialog::AnyFile);

    dialog.setNameFilter("PNG images (*.png)");

    dialog.setDefaultSuffix("png");

    if (dialog.exec())
    {
        QString fileName = *(dialog.selectedFiles().begin());

        SheetPixmap->save(fileName, "PNG");
    }
}



void MainWindow::SaveAnimationParams()
{
    QFileDialog dialog(this);

    dialog.setAcceptMode(QFileDialog::AcceptSave);

    dialog.setFileMode(QFileDialog::AnyFile);

    dialog.setNameFilter("XML files (*.xml)");

    dialog.setDefaultSuffix("xml");

    if (dialog.exec())
    {
        QString fileName = *(dialog.selectedFiles().begin());

        QFile file(fileName);
        if (file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
             QTextStream outStream(&file);
             outStream << AnimationParamsText;
        }

    }
}

void MainWindow::AnimateCheckBoxStateChanged(int state)
{
    if (state == Qt::Checked)
    {
        currentFrameOnTimer = 0;



        AnimTimer.setInterval(Animation->GetFrame(currentFrameOnTimer).TimeToPlay);
        AnimTimer.start();
    }
    else
    {
        AnimTimer.stop();
    }

}

void MainWindow::TimerTimeout()
{


    int prevFrameTime = Animation->GetFrame(currentFrameOnTimer).TimeToPlay;

    currentFrameOnTimer++;

    if (currentFrameOnTimer >= Animation->GetFrameCount())
    {
        currentFrameOnTimer = 0;
    }

    TFrame& frame = Animation->GetFrame(currentFrameOnTimer);

    int timeToPlay = frame.TimeToPlay - prevFrameTime;

    if (timeToPlay < 0)
    {
        timeToPlay = 0;
    }


    int newPosX = frameImageDefaultPosX + frame.ShiftX;
    int newPosY = frameImageDefaultPosY + frame.ShiftY;

    ui->FrameImage->move(newPosX, newPosY);
    ui->FrameImage->setPixmap(*(frame.Pixmap));

    AnimTimer.setInterval(timeToPlay);
    AnimTimer.start();

}

void MainWindow::SelectFrame(int i)
{
    TFrame& frame = Animation->GetFrame(i);

    ui->FrameImage->setPixmap(*(frame.Pixmap));

    int newPosX = frameImageDefaultPosX + frame.ShiftX;
    int newPosY = frameImageDefaultPosY + frame.ShiftY;

    ui->FrameImage->move(newPosX, newPosY);

    ui->ShiftX_spinBox->setValue(frame.ShiftX);
    ui->ShiftY_spinBox->setValue(frame.ShiftY);

    ui->TimeFrameEdit->setText(QString::number(frame.TimeToPlay));

}

void MainWindow::LoadFrame(const std::string& text)
{
    ui->FrameList->addItem(QString(text.c_str()));

}

void MainWindow::Clear()
{
    AnimTimer.stop();

    //ui->FrameImage->pixmap()->fill();

    ui->AnimateCheckBox->setChecked(false);

    ui->OutputXmlFile->clear();

    ui->FrameList->clear();

    Animation->Clear();
}
