/***************************************************************************
**
**  This file is part of SciFigs.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file is distributed in the hope that it will be useful, but WITHOUT
**  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
**  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2003-08-14
**  Copyright: 2003-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "ImageWidget.h"
#include "ImageWidgetProperties.h"
#include "GraphicObjectFactory.h"

namespace SciFigs {

/*!
  \class ImageWidget ImageWidget.h
  \brief The ImageWidget is a widget that contains an image and that can be printed.
 
  It is usually docked in GraphicSheet to construct complex figures including results from other software not producing results complying with SciFigs strandards (".page" or similar files).
*/

const QString ImageWidget::xmlImageWidgetTag="ImageWidget";

REGISTER_GRAPHICOBJECT(ImageWidget, ImageWidget::xmlImageWidgetTag,
                        QApplication::translate("ImageWidget", "Image"),
                        QApplication::translate("ImageWidget", "&Image"),
                        QApplication::translate("ImageWidget", "Ctrl+I"),
                        QApplication::translate("ImageWidget", "Display an image loaded from disk"));

ImageWidget::ImageWidget(QWidget * parent) :
    GraphicObject(parent)
{
  TRACE;
  setConstantWidthHeightRatio(true);
}

ImageWidget::~ImageWidget()
{
  TRACE;
}

void ImageWidget::paintEvent(QPaintEvent * e)
{
  TRACE;
  const QRect & r=e->rect();
  QPainter p(this);
  p.drawPixmap(r.left(), r.top(), _pixmap, r.left(), r.top(), r.width(), r.height());
}

void ImageWidget::resizeEvent(QResizeEvent * )
{
  TRACE;
  update();
}

void ImageWidget::updateMask()
{
  TRACE;
  setMask(_pixmap.createHeuristicMask());
}

void ImageWidget::update()
{
  TRACE;
  _pixmap=QPixmap(width(), height());
  if(_trueImage.isNull()) {
    QPainter p(&_pixmap);
    p.fillRect(0, 0, width(), height(), Qt::white);
    p.setFont(font());
    p.setPen(Qt::red);
    p.drawText(0, 0, width(), height(), Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap, "Empty Image" );
  } else {
    QImage tmp=_trueImage.scaled (width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    _pixmap=QPixmap::fromImage(tmp, Qt::AutoColor | Qt::DiffuseDither | Qt::DiffuseAlphaDither |
                                  Qt::PreferDither);
  }
  GraphicObject::update();
}

void ImageWidget::paint(QPainter& p, double, int w, int h, bool)
{
  TRACE;
  QImage tmp=_trueImage.scaled (w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  p.drawImage(0, 0, tmp, 0, 0, -1, -1, Qt::AutoColor | Qt::DiffuseDither | Qt::DiffuseAlphaDither |
               Qt::PreferDither);
}

void ImageWidget::loadImage()
{
  TRACE;
  if(_fileName.length() > 0) {
    QFileInfo fi(_fileName);
    if(!fi.exists()) {
      PathTranslatorOptions options;
      options.setTitle(tr("Open an existing image"));
      options.setFileType(tr( "Image file (%1)" ));
      QString fn=Application::instance()->translatePath(_fileName, options);
      if(fn.isEmpty()) return;
      fi.setFile(fn);
    }
    if(fi.exists()) {
      _fileName=fi.absoluteFilePath();
      _trueImage.load(_fileName);
      // With Qt4, even for a PNG the deduced resolution is always the ScreenResolution
      double xResol=(double) _trueImage.dotsPerMeterX() * 0.01;
      double yResol=(double) _trueImage.dotsPerMeterY() * 0.01;
      if(xResol==0.0) xResol=118.11; // 300 dpi converted in dot/cm
      if(yResol==0.0) yResol=118.11; // 300 dpi converted in dot/cm
      _printWidth=(double) _trueImage.width()/xResol;
      _printHeight=(double) _trueImage.height()/yResol;
      double maxResol=xResol;
      if(yResol > maxResol) maxResol=yResol;
      setPrintResolution(( int) floor(maxResol * 2.54 + 0.5) ); // in dpi
      emit sizeChanged();
      update();
    }
  }
}

bool ImageWidget::xml_polish(XML_POLISH_ARGS)
{
  TRACE;
  if(!fileName().isEmpty()) {
    double tmpWidth=printWidth();
    double tmpHeight=printHeight();
    loadImage();
    setPrintWidth(tmpWidth);
    setPrintHeight(tmpHeight);
  }
  GraphicObject::xml_polish(context);
  return true;
}

uint ImageWidget::_category=PropertyProxy::uniqueId();
uint ImageWidget::_tabLink=PropertyProxy::uniqueId();

/*!
  Setup property editor
*/
void ImageWidget::addProperties(PropertyProxy * pp)
{
  TRACE;
  GraphicObject::addProperties(pp);
  if(!pp->setCurrentCategory(_category)) {
    pp->addCategory(_category, tr("Image"), QIcon(":ImageWidget.png"));
  }
  if(pp->setCurrentTab(_tabLink)) {
    pp->addReference(this);
  } else {
    ImageWidgetProperties * w=new ImageWidgetProperties;
    pp->addTab(_tabLink, tr("Link"), w, this);
  }
}


/*!
  Cleanup property editor
*/
void ImageWidget::removeProperties(PropertyProxy * pp)
{
  TRACE;
  GraphicObject::removeProperties(pp);
  if(pp->setCurrentCategory(_category)) {
    pp->removeTab(_tabLink, this);
  }
}

void ImageWidget::properties(PropertyWidget * w) const
{
  TRACE;
  if(w->id()==_tabLink) {
    w->setValue(ImageWidgetProperties::ImageFile, fileName());
  } else {
    GraphicObject::properties(w);
  }
}

/*!
  Set value \a val to property \a id, after a user action in property editor
*/
void ImageWidget::setProperty(uint wid, int pid, QVariant val)
{
  TRACE;
  if(wid==_tabLink) {
    switch(pid) {
    case ImageWidgetProperties::ImageFile:
      setFileName(val.toString());
      loadImage();
      break;
    }
  } else {
    GraphicObject::setProperty(wid, pid, val);
  }
}

} // namespace SciFigs
