/****************************************************************************
** vimg - main.cpp, vimg.cpp, vimg.h, vimg.qrc, vimg.ui
**---------------------------------------------------------------------------
** FJA - neocipres@gmail.com                Diciembre de 2008   (29/09/10)
**===========================================================================
** This file may be used under the terms of the GNU General Public
** License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

#include "vimg.h"
#include <QMessageBox>
#include <QDir>
//#include <QFileDialog>
#include <QScrollArea>
#include <QTimer>
#include <QKeyEvent>
#include <QTransform>
#include <QScrollBar>
#include <QPixmap>
#include <Qt3Support>
#include <Qt3Support/Q3FilePreview>
#include <Qt3Support/Q3FileDialog>
#include <Qt3Support/Q3Url>

class Preview : public QLabel, public Q3FilePreview
    {
    public:
        Preview( QWidget *parent=0 ) : QLabel( parent ) {}

        void previewUrl(const Q3Url &u)
        {
            QString path = u.path();
            QPixmap pix(path);
            if ( pix.isNull() )
                    setText(u.fileName());
            else {
                    if ( pix.width ( ) > 160 ) {
                         QSize t = QSize::QSize (160, 120);
                         pix = pix.scaled(t, Qt::KeepAspectRatio); // Qt::KeepAspectRatio Qt::IgnoreAspectRatio
                        }
                    setPixmap( pix );
                 }
        }
    };

MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
{
    ui.setupUi(this);
    dirT = QDir::currentPath();
    ajuste = false;
    escalar = true;
    i = 0;
    parar = true;
    imgs << ":/new/prefix1/imagenes/vimg.png";
    tiempo = new QTimer(this);
    tiempo->start(3000);

    ui.centralwidget->setFocusPolicy(Qt::StrongFocus); // para poder recoger los eventos del teclado ???
    ui.tLImagen->setBackgroundRole(QPalette::Base);
    ui.tLImagen->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);//clave para ajustar a la ventana!
    ui.tLImagen->setScaledContents(true);

    scrollArea = new QScrollArea(ui.centralwidget);
    ui.vboxLayout->addWidget(scrollArea);
    scrollArea->setBackgroundRole(QPalette::Midlight); // Mid, Light, Midlight, Shadow, Dark
    scrollArea->setWidget(ui.tLImagen);
    scrollArea->setAlignment(Qt::AlignCenter);

    QObject::connect(ui.actionAcerca_de_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    QObject::connect(ui.actionAcerca_de_Vimg, SIGNAL(triggered()), this, SLOT(acercade()));
    QObject::connect(ui.pBDir, SIGNAL(clicked()), this, SLOT(abrirDir()));
    QObject::connect(ui.actionAbrir, SIGNAL(triggered()), this, SLOT(abrirDir()));
    QObject::connect(ui.pBSiguiente, SIGNAL(clicked()), this, SLOT(posterior()));
    QObject::connect(ui.pBAnterior, SIGNAL(clicked()), this, SLOT(anterior()));
    QObject::connect(ui.cBAjustar, SIGNAL(clicked()), this, SLOT(ajustarImg()));
    QObject::connect(ui.cBEscalar, SIGNAL(clicked()), this, SLOT(escalarImg()));
    QObject::connect(ui.pBStop, SIGNAL(clicked()), this, SLOT(stop()));
    QObject::connect(ui.pBPlay, SIGNAL(clicked()), this, SLOT(activarPlay()));
    QObject::connect(tiempo, SIGNAL(timeout()), this, SLOT(play()));
    QObject::connect(ui.cBListaImg, SIGNAL(currentIndexChanged(int)), this, SLOT(cambiaItem(int)));
    QObject::connect(ui.actionNormal, SIGNAL(triggered()), this, SLOT(imagenNormal()));
    QObject::connect(ui.actionZoomIn, SIGNAL(triggered()), this, SLOT(zoomIn()));
    QObject::connect(ui.actionZoomOut, SIGNAL(triggered()), this, SLOT(zoomOut()));
}

MainWindow::~MainWindow()
{

}

void MainWindow::acercade()
{
 QString separador = QString::null;
 separador.fill('=', 51);
 QString teclas = QString::null;
 teclas.append(QString::fromUtf8("<p>A -> ajustar imagen al tamaño de la ventana</p>" ));
 teclas.append(QString::fromUtf8("<p>R -> rotar la imagen 90º derecha</p>"));
 teclas.append(QString::fromUtf8("<p>L -> rotar la imagen 90º izquierda</p>"));
 teclas.append(QString::fromUtf8("<p>home, end, PageUp, PageDown -> saltar a la imagen correspondiente</p>"));
 QString nomAp = "<p><b><BIG><BIG>VImg</BIG></BIG></b></p>";
 QString desAp1 = "<p><b>"+QString::fromUtf8("Visor de imágenes")+"</b></p>";
 QString desAp2 = "<p>Desarrollado con <a href= http://trolltech.com/developer/qt-creator>Qt Creator</a>, tomando como base el ejemplo Image Viewer del Qt Toolkit.</p>";
 QString autor =  "<p><b>FJA</b> - neocipres@gmail.com</p>";
 QString version = QString::fromUtf8("<p>Versión: 0.9.8</p>");
 QString modificado = "<p>Diciembre de 2008  -  Modificado el 29 de Sep/2010</p>";
 QString licencia = QString::fromUtf8("<p>Distribuido de acuerdo a los términos de la <a href= http://www.viti.es/gnu/licenses/gpl.html>licencia GNU/GPL</a></p>");
 QString  gnu = "<p><a href= http://www.gnu.org/home.es.html>Proyecto GNU</a></p>";
 QMessageBox::about(ui.centralwidget, "Acerca de ...",nomAp+desAp1+desAp2+teclas+separador+autor+modificado+separador+version+licencia+gnu);

}

void MainWindow::abrirDir()
{
 /*imgs = QFileDialog::getOpenFileNames(
    ui.centralwidget,
    QString::fromUtf8("Selecciona uno o más archivos para abrir"),
    dirT,
    QString::fromUtf8("Imágenes (*.png *.jpg *.bmp *.jpeg *.gif *.xpm *.pbm *.pgm *.ppm *.tiff *.xbm)")); */

 Preview* p = new Preview;
 QString filtro =  QString::fromUtf8("Imágenes (*.png *.jpg *.bmp *.jpeg *.gif *.xpm *.pbm *.pgm *.ppm *.tiff *.xbm)");
 Q3FileDialog* fd = new Q3FileDialog(this);
 fd->setCaption(QString::fromUtf8("Elige las imágenes ..."));
 fd->setDir(dirT);
 fd->addFilter(filtro);
 fd->setMode(Q3FileDialog::ExistingFiles);
 fd->setViewMode(Q3FileDialog::Detail);
 fd->setContentsPreviewEnabled(true);
 fd->setContentsPreview(p, p);
 fd->setPreviewMode(Q3FileDialog::Contents);
 //fd->selectAll(true);
 if (fd->exec() == QDialog::Accepted) imgs = fd->selectedFiles();

 QDir d;
 if (imgs.size() !=0)
 {
  imgs.sort();
  QFile f(imgs[0]);
  QFileInfo fi(f);
  dirT = fi.absolutePath();
  ui.cBListaImg->clear();
  for (int n = 0; n < imgs.size(); ++n)
  {
    f.setFileName(imgs[n]);
    fi.setFile(f);
    ui.cBListaImg->addItem(fi.fileName());
  }
 }
  else
  {
   dirT = d.homePath();
   imgs << ":/new/prefix1/imagenes/vimg.png";
   ui.cBListaImg->clear();
  }

 ui.statusbar->showMessage("Directorio: " + dirT + ", con " + QString::number(imgs.size()) + " archivos de imagen seleccionados");
 escala = 1.0;
 actualizar();
 i = 0;
 if (parar && imgs.size() !=0) saltoImg();
}

void MainWindow::actualizar()
{
 ui.actionZoomIn->setEnabled(!ajuste);
 ui.actionZoomOut->setEnabled(!ajuste);
 ui.actionNormal->setEnabled(!ajuste);
}

void MainWindow::ajustarImg()
{
 ajuste = ui.cBAjustar->isChecked();
 scrollArea->setWidgetResizable(ajuste);
 if (!ajuste) ui.tLImagen->adjustSize();
 actualizar();
 }

void MainWindow::escalarImg()
{
 escalar = ui.cBEscalar->isChecked();
 saltoImg();
}

void MainWindow::posterior()
{
 if (i == imgs.size() - 1) i = 0; else i += 1;
 saltoImg();
}

void MainWindow::anterior()
{
 if (i == 0) i = imgs.size() - 1; else i -= 1;
 saltoImg();
}

void MainWindow::saltoImg()
{
 QString mensaje;
 try {
      QImage *imagen = new QImage(imgs[i]);
      QPixmap pix = QPixmap::fromImage(*imagen) ;

      if (!ajuste && escalar)
      {
          int ancho = ui.centralwidget->width();
          int alto = ui.centralwidget->height();
          if ( pix.height() > alto || pix.width() > ancho)
          {
            QSize t = QSize::QSize (ancho, alto);
            pix = pix.scaled(t, Qt::KeepAspectRatio);

        }
      }

      ui.tLImagen->setPixmap(pix);
      if (!ajuste) ui.tLImagen->adjustSize();
      mensaje = "Archivo "+QString::number(i+1)+"/"+QString::number(imgs.size())+" -> "+imgs[i]+" de "+QString::number(imagen->width())+"x"+QString::number(imagen->height());
      ui.statusbar->showMessage(mensaje);
      imagen->~QImage();

 } catch (...) {
      if (imgs.size() != 0)
                       mensaje = "Error al cargar el archivo: " + imgs[i];
                else
                       mensaje = "Error -> no hay imágenes";

      QMessageBox::information(ui.centralwidget, mensaje, "");
 }
}

void MainWindow::activarPlay()
{
 parar = false;
 ui.statusbar->showMessage("Reproduciendo el directorio: " + dirT, 3000) ;
}

void MainWindow::play()
{
 if (!parar && !imgs.empty()) posterior();
}

void MainWindow::stop()
{
 parar = true;
 ui.statusbar->showMessage(QString::fromUtf8("Detenida la reproducción del directorio: ") + dirT, 3000);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
 int tecla = event->key();
 switch (tecla) {
    case Qt::Key_PageUp:
        anterior();
        break;
    case Qt::Key_PageDown:
        posterior();
        break;
    case Qt::Key_End:
        i = imgs.size()-1;
        saltoImg();
        break;
    case Qt::Key_Home:
        i = 0;
        saltoImg();
        break;
    case Qt::Key_A:
        if (ajuste) ui.cBAjustar->setCheckState(Qt::Unchecked); else ui.cBAjustar->setCheckState(Qt::Checked);
        ajustarImg();
        break;
    case Qt::Key_R:
        rotarImg(90);
        break;
    case Qt::Key_L:
        rotarImg(-90);
        break;

 }
}

void MainWindow::cambiaItem(int index)
{
 i = index;
 if (imgs.size() != 0 && i != -1) saltoImg();
}

void MainWindow::rotarImg(int angulo)
{
 QTransform transform;
 transform.rotate(angulo);
 QPixmap imgt = ui.tLImagen->pixmap()->transformed(transform);
 ui.tLImagen->resize(imgt.width(), imgt.height());
 ui.tLImagen->setPixmap(imgt.copy());
}

void MainWindow::escalaImg(double factor)
{
 escala *= factor;
 ui.tLImagen->resize(ui.tLImagen->pixmap()->size()*escala);
 adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
 adjustScrollBar(scrollArea->verticalScrollBar(), factor);
 ui.actionZoomIn->setEnabled(escala < 3.0);
 ui.actionZoomOut->setEnabled(escala > 0.333);
}

void MainWindow::adjustScrollBar(QScrollBar *scrollBar, double factor)
{
  scrollBar->setValue(int(factor * scrollBar->value() + ((factor - 1) * scrollBar->pageStep()/2)));
}

void MainWindow::zoomIn()
{
 escalaImg(1.25);
}

void MainWindow::zoomOut()
{
 escalaImg(0.8);
}

void MainWindow::imagenNormal()
{
 ui.tLImagen->adjustSize();
 escala = 1.0;
}