//==============================================
//  copyright            : (C) 2003-2005 by Will Stokes
//==============================================
//  This program is free software; you can redistribute it
//  and/or modify it under the terms of the GNU General
//  Public License as published by the Free Software
//  Foundation; either version 2 of the License, or
//  (at your option) any later version.
//==============================================

//Systemwide includes
#include <qpixmap.h>
#include <qstring.h>
#include <qpainter.h>
#include <qfontmetrics.h>
#include <qapplication.h>
#include <qrect.h>
#include <qbitmap.h>

//Projectwide includes
#include "photoPreviewWidget.h"
#include "photosIconView.h"
#include "window.h"
#include "../config.h"
#include "../backend/photo.h"
#include "../backend/tools/guiTools.h"

//==============================================
PhotoPreviewWidget::PhotoPreviewWidget( QIconView *parent, Photo* phto ) :
                                   QIconViewItem( parent, QString(""), QPixmap(phto->getThumbnailFilename()) )
{
  //initially item not moused over, set photo pointer
  mousedOver = false;
  this->phto = phto;

  //calibrated text width is icon width minus margin + info button size (info button is sized to be a square of height
  //equal to text height, aka fm.height)
  QFontMetrics fm( qApp->font() );
  calibratedWidth = THUMBNAIL_WIDTH - PHOTO_TEXT_MARGIN - fm.height();
  
  //actually set the items text by clipping it using the calibration width we just computed
  setText( phto->getDescription() );

  //update the items rectange which is a function of the text width, icon rect,
  //and margins for displaying selection and mouse over ovals
  initializeItemRect();
}
//==============================================
Photo* PhotoPreviewWidget::getPhoto()
{
  return phto;
}
//==============================================
void PhotoPreviewWidget::updateImage()
{
  setPixmap( QPixmap(phto->getThumbnailFilename()), false);
}
//==============================================
void PhotoPreviewWidget::setPixmap(const QPixmap& p, bool redraw )
{
  pixmapXOffset = (THUMBNAIL_WIDTH - p.width() ) / 2;  
  pixmapYOffset = (THUMBNAIL_HEIGHT - p.height() ) / 2;  
  QIconViewItem::setPixmap( p, redraw );
}
//==============================================
void PhotoPreviewWidget::updateDescription()
{
  setText( phto->getDescription() );
}
//==============================================
void PhotoPreviewWidget::setText ( const QString & text )
{
  QIconViewItem::setText( clipText(text, 1, calibratedWidth), false );
}
//==============================================
void PhotoPreviewWidget::paint( QPainter *p )
{
  //create colors
  QColor offWhite( 255, 255, 255 );
  QColor darkBlue(35, 75, 139);
  QColor paperColor;

  //draw offwhite or selected color depending on if photo is selected
  QRect paperRect( x(), y(),
                              2*PHOTO_MARGIN + pixmapRect().width(),
                              2*PHOTO_MARGIN + pixmapRect().height() + PHOTO_TEXT_MARGIN + textRect().height() );
  if(isSelected())
    paperColor = darkBlue;
  else
    paperColor = offWhite;
  p->fillRect(  paperRect, QBrush( paperColor ) );

  //paint pixmap
  p->drawPixmap( x() + pixmapRect().x() + pixmapXOffset + 1,
                                 y() + pixmapRect().y() + pixmapYOffset + 1, 
                                 *pixmap());
  
  //paint text
  int align = AlignLeft | AlignTop | BreakAnywhere;
  if(isSelected())
    p->setPen( white );
  else
    p->setPen( black );
  p->drawText( x() + textRect().x() + 1, y() + textRect().y() + 1, 
                           textRect().width(), textRect().height(),
                           align, text() );
}
//==============================================
void PhotoPreviewWidget::paintItem( QPainter* p, const QColorGroup&)
{
  //resize old static buffer to new needed size, fill with widget background color
  static QPixmap buffer;
  QRect r = rect();
  QSize newSize = r.size().expandedTo(buffer.size() );
  buffer.resize(newSize);
  buffer.fill( white );

  //construct painter for buffer
  QPainter bufferPainter(&buffer, this);
  bufferPainter.translate( -r.x(), -r.y() );
 
   //paint item
  paint(&bufferPainter);

  //paint edit button
  if(mousedOver)
  {
    QRect photoInfoRect = getPhotoInfoRect();
    bufferPainter.drawPixmap( photoInfoRect, * (((Window*) qApp->mainWidget())->photoInfo) );
  }

  //paint shadows
  QPixmap* shadowBL, *shadowB, *shadowBR, *shadowR, *shadowTR;
  Window* window = (Window*) qApp->mainWidget();
  shadowBL = window->shadowBL;
  shadowB = window->shadowB;
  shadowBR = window->shadowBR;
  shadowR = window->shadowR;
  shadowTR = window->shadowTR;

  QRect shadowRect;
  shadowRect.setLeft( x() + PHOTO_SHADOW_END_OFFSET );
  shadowRect.setRight( shadowRect.left() + PHOTO_SHADOW );
  shadowRect.setTop( y() + rect().height() - PHOTO_SHADOW );
  shadowRect.setBottom( shadowRect.top() + PHOTO_SHADOW );
  bufferPainter.drawPixmap( shadowRect, *shadowBL );

  shadowRect.setLeft( shadowRect.right() + 1 );
  shadowRect.setRight( x() +  rect().width() - PHOTO_SHADOW - 1 );
  bufferPainter.drawPixmap( shadowRect, *shadowB );

  shadowRect.setLeft( shadowRect.right() + 1 );
  shadowRect.setRight( shadowRect.left() + PHOTO_SHADOW );
  bufferPainter.drawPixmap( shadowRect, *shadowBR );

  shadowRect.setBottom( shadowRect.top() - 1 );
  shadowRect.setTop( y() +PHOTO_SHADOW_END_OFFSET + PHOTO_SHADOW );
  bufferPainter.drawPixmap( shadowRect, *shadowR );

  shadowRect.setBottom( shadowRect.top() - 1 );
  shadowRect.setTop( y() +PHOTO_SHADOW_END_OFFSET );
  bufferPainter.drawPixmap( shadowRect, *shadowTR );
  
  //draw buffer to screen
  p->drawPixmap( x(), y(), buffer );
}
//==============================================
void PhotoPreviewWidget::paintFocus( QPainter*, const QColorGroup& ) { }
//==============================================
bool PhotoPreviewWidget::acceptDrop( const QMimeSource *) const
{
  return true;
}
//==============================================
int PhotoPreviewWidget::compare ( QIconViewItem * i ) const
{
  if( pos().y() > (i->pos().y() + height()) ||
      (
        pos().y() >= i->pos().y() &&
        pos().x() >= i->pos().x()
      ))
  { return 1; }
  else
  { return -1; }
}
//==============================================
void PhotoPreviewWidget::initializeItemRect()
{
  //set pixmap rect to be offset slightly from top left corner (by photo margin)
  QRect pr = pixmapRect();
  int itemLeft = x();
  int itemTop = y();
  
  pixmapXOffset = (THUMBNAIL_WIDTH - pixmap()->width() ) / 2;  
  pixmapYOffset = (THUMBNAIL_HEIGHT - pixmap()->height() ) / 2;  
  
  pr.setLeft( x() + PHOTO_MARGIN );
  pr.setRight( pr.left() + THUMBNAIL_WIDTH );
  pr.setTop( y() + PHOTO_MARGIN );
  pr.setBottom( pr.top() + THUMBNAIL_HEIGHT );
  setPixmapRect( pr );

  //move text rect to be below new pixmap region.
  //reset height to allow for up to 3 lines of text.
  QFontMetrics fm( qApp->font() );
  QRect tr = QRect();
  tr.setLeft( x() + PHOTO_MARGIN );
  tr.setRight( tr.left() +THUMBNAIL_WIDTH );
  tr.setTop( y() + PHOTO_MARGIN + THUMBNAIL_HEIGHT + PHOTO_TEXT_MARGIN );
  tr.setBottom( tr.top() + 0*fm.leading() + 1*fm.height() );
  setTextRect( tr );

  //set overall item rect
  int itemW = THUMBNAIL_WIDTH + 2*PHOTO_MARGIN + PHOTO_SHADOW;
  int itemH = THUMBNAIL_HEIGHT + PHOTO_TEXT_MARGIN + textRect().height() + 2*PHOTO_MARGIN + PHOTO_SHADOW;
  setItemRect( QRect( itemLeft, itemTop, itemW, itemH ) );
}
//==============================================
void PhotoPreviewWidget::setMousedOver(bool val)
{ 
  mousedOver = val;   
}
//==============================================
QRect PhotoPreviewWidget::getPhotoInfoRect()
{
  QRect photoInfoRect;
  QFontMetrics fm( qApp->font() );
  photoInfoRect.setLeft( x() + rect().width() - fm.height() - PHOTO_MARGIN - PHOTO_SHADOW - 1 );
  photoInfoRect.setRight( photoInfoRect.left() + fm.height() );
  photoInfoRect.setTop( y() + rect().height() - fm.height() - PHOTO_MARGIN - PHOTO_SHADOW - 1 );
  photoInfoRect.setBottom( photoInfoRect.top() + fm.height() );
  return photoInfoRect;
}
//==============================================
QPoint PhotoPreviewWidget::getPhotoPos()
{
  //get widget coordiantes of item
  int xpos,ypos;
  xpos = x() + pixmapRect().x() + pixmapXOffset + 1;
  ypos = y() + pixmapRect().y() + pixmapYOffset + 1;
  
  //shift by scrolled amount
  xpos-= iconView()->contentsX();
  ypos-= iconView()->contentsY();

  //offset by viewport top left
  //(why not iconview topleft? item actually placed in viewport which is placed in iconview. this
  //viewport can be offset (and when I wrote this code it was) from the iconview depending on Trolltech's
  //scrollview code which can using spacing between the viewport and scrolls widgets. since the viewport
  //is a full blown widget, we can figure out it's reall screen coordinates and need not consult the iconview object at all.
  QPoint viewportTL = iconView()->viewport()->mapToGlobal( QPoint(0,0) );
  xpos+= viewportTL.x();
  ypos+= viewportTL.y();

  return QPoint(xpos,ypos);
}
//==============================================
