//==============================================
//  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 <qiconview.h>
#include <qfontmetrics.h>
#include <qapplication.h>

//Projectwide includes
#include "subalbumPreviewWidget.h"
#include "subalbumsIconView.h"
#include "../backend/subalbum.h"
#include "../backend/photo.h"
#include "../backend/tools/imageTools.h"
#include "subalbumsWidget.h"
#include "layoutWidget.h"
#include "subalbumWidget.h"
#include "photoPreviewWidget.h"
#include "../backend/tools/guiTools.h"

#include "../backend/album.h"

//==============================================
SubalbumPreviewWidget::SubalbumPreviewWidget( SubalbumsIconView* parent, Subalbum* salbum )
          : QIconViewItem(parent, 
                          clipText( salbum->getName(), 2, parent->getTextWidth()),
                          *salbum->getRepresentativeImage(MEDIUM) )
{         
  mousedOver = false;
  this->parent = parent;
  subalbum = salbum;
  
  //initialize item rectangle
  initializeItemRect();
}
//==============================================
Subalbum* SubalbumPreviewWidget::getSubalbum()
{
  return subalbum;
}
//==============================================
void SubalbumPreviewWidget::paintFocus( QPainter*, const QColorGroup& ) { }
//==============================================
void SubalbumPreviewWidget::paint( QPainter *p )
{
  paintItem( p, QColorGroup() );
}
//==============================================
void SubalbumPreviewWidget::paintItem( QPainter* p, const QColorGroup&)
{
  QColor lightLightBlue( 152, 180, 226 );
  QColor darkLightBlue(193, 210, 238);
  QColor darkBlue(35, 75, 139);
  QColor background = darkLightBlue;
  
  //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( background );

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

  //turn off clipping to make painting operations faster
  bufferPainter.setClipping(false);
  
  //paint mouse over or actual selection color
  bool paintRect = false;
  QColor paintColor;
  if(isSelected()) { paintColor = darkBlue; paintRect = true; }
  else if(mousedOver) { paintColor = lightLightBlue; paintRect = true; }

  if(paintRect)
  {
     //first paint alpha blended edges

     //-------------------------
     //top and bottom edges
     QRect r2 = r;
     r2.setLeft( r.left() + 4);
     r2.setRight( r.right() - 4);
     r2.setTop( r.top() );
     r2.setBottom( r.bottom() );
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40 ) );

     r2.setLeft( r2.left() + 1);
     r2.setRight( r2.right() - 1);
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67 ) );
     //-------------------------
     //inner top and bottom edges
     r2.setLeft( r2.left() - 3);
     r2.setRight( r2.right() + 3);
     r2.setTop( r2.top() + 1 );
     r2.setBottom( r2.bottom() - 1);
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40 ) );

     r2.setLeft( r2.left() + 1);
     r2.setRight( r2.right() - 1);
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67 ) );
     //-------------------------
     //left and right inner edges
     r2.setLeft( r2.left() - 2);
     r2.setRight( r2.right() + 2);
     r2.setTop( r2.top() + 1 );
     r2.setBottom( r2.bottom() - 1);
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40) );

     r2.setTop( r2.top() + 1);
     r2.setBottom( r2.bottom() - 1);
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67) );
     //-------------------------
     // middle region
     r2.setLeft( r2.left() - 1 );
     r2.setRight( r2.right() + 1 );
     r2.setTop( r2.top() + 1);
     r2.setBottom( r2.bottom() - 1);
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40) );

     r2.setTop( r2.top() + 1);
     r2.setBottom( r2.bottom() - 1);
     bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67) );
     //-------------------------
     //second paint inner selection
     r2 = r;
     r2.setLeft( r.left() + 1);
     r2.setRight( r.right() - 1);
     r2.setTop( r.top() + 4 );
     r2.setBottom( r.bottom() - 4);
     bufferPainter.fillRect( r2, paintColor );

     r2.setLeft( r2.left() + 1);
     r2.setRight( r2.right() - 1);
     r2.setTop( r2.top() - 2 );
     r2.setBottom( r2.bottom() + 2 );
     bufferPainter.fillRect( r2, paintColor );

     r2.setLeft( r2.left() + 2);
     r2.setRight( r2.right() - 2);
     r2.setTop( r2.top() - 1 );
     r2.setBottom( r2.bottom() + 1 );
     bufferPainter.fillRect( r2, paintColor );
  }

  //paint pixmap
  bufferPainter.drawPixmap( x()+4 , y() + 4, *pixmap());

  //paint text
  int align = AlignLeft | AlignTop | BreakAnywhere;
  if(isSelected())
    bufferPainter.setPen( white );
  else
    bufferPainter.setPen( black );
  bufferPainter.drawText( x() + 4 + pixmapRect().width(),
                                        y() + 4,
                                        textRect().width(), textRect().height(),
                                        align, text() );

  //draw buffer to screen
  p->drawPixmap( x(), y(), buffer );
}
//==============================================
void SubalbumPreviewWidget::dropped( QDropEvent *e, const QValueList<QIconDragItem> & )
{
  //if source is not from the application then ignore
  if(e->source() == NULL)
    return;
    
  //if source of drop event is from this widget when user is attempting to
  //rearrange subalbums, move currently selected item to
  //approximately where the cursor is before rearranging items
  if(e->source()->parentWidget() == parent)
  {
    if(e->pos().y() < (y() + (height()/2)))
    {
      parent->currentItem()->move(x(), y() - 1);
    }
    else
    {
      parent->currentItem()->move(x(), y() + (height()/2) + 1);
    }
  }
  //else check to see if user dropped photo(s) on subalbum
  else
  {
    //if the source of the items is the current subalbum icon view and
    //this is a different subalbum then
    //move photos from that subalbum to this one
    if(
         !isSelected() &&
         (
           e->source()->parentWidget() ==
           ((LayoutWidget*)(parent->parentWidget()->parentWidget()))->getSubalbum()->getPhotos()
         )
       )
    {
      //iterate over all selected photos, inserting each
      //into this subalbum, removing from old subalbum,
      //and deleting old photo widgets
      SubalbumWidget* oldSubalbumWidget = ((LayoutWidget*)(parent->parentWidget()->parentWidget()))->getSubalbum();
      Subalbum* oldSubalbum = oldSubalbumWidget->getSubalbum();
      QIconViewItem* current = oldSubalbumWidget->getPhotos()->firstItem();
      while(current != NULL)
      {
       //found a selected photo
        if(current->isSelected())
        {
          //get pointer to photo
          Photo* photo = ((PhotoPreviewWidget*)current)->getPhoto();

          //remove photo from that subalbum
          oldSubalbum->photoMoved(photo);

          //add photo to this subalbum
          subalbum->addPhoto(photo);

          //delete photo widget and rearrange photos
          QIconViewItem* temp = current;
          current = current->nextItem();
          delete temp;
        }
        else
        {
          current = current->nextItem();
        }
      } //end while

      //reannarge photos once all photos have been removed
      oldSubalbumWidget->getPhotos()->arrangeItemsInGrid();
    }
  }
}
//==============================================
bool SubalbumPreviewWidget::acceptDrop( const QMimeSource *) const
{
  return true;
}
//==============================================
int SubalbumPreviewWidget::compare ( QIconViewItem * i ) const
{
  if(pos().y() >= i->pos().y())
  {  return 1; }
  else
  { return -1; }
}
//==============================================
QPixmap* SubalbumPreviewWidget::createSubalbumPixmap( QString imageName )
{
  //load image
  QImage icon(imageName);

  //if null then bail immediately
  if( icon.isNull() )
    return NULL;
  
  //----------------------------------------------
  //resize image based on text properties. Find ideal hight
  QFontMetrics fm( qApp->font() );

  //ideal image height is two text lines, 1 pixel inbetween
  int idealImageHeight = fm.leading() + 2*fm.height();

 //ideal image width assuming 4:3 aspect ratio
 int idealImageWidth = (4 * idealImageHeight ) / 3;
 //----------------------------------------------
 //resize image to fit within bounding rectangle, pad and center as necessary
 int actualImageWidth = 0;
 int actualImageHeight = 0;
 calcScaledImageDimensions( icon.width(), icon.height(),
                            idealImageWidth, idealImageHeight,
                            actualImageWidth, actualImageHeight );

  //if off by one pixel fudge it so icon perfectly cenetered
  if(actualImageHeight == idealImageHeight - 1)
  {
    actualImageHeight = idealImageHeight;
  }

  QImage scaledIcon= icon.smoothScale( actualImageWidth, actualImageHeight );
  QImage* paddedScaledIcon = new QImage(idealImageWidth, idealImageHeight, scaledIcon.depth());
  paddedScaledIcon->setAlphaBuffer(true);

  //make entire image transparent
  int x, y;
  for(x=0; x< idealImageWidth; x++)
  {
    for(y=0; y<idealImageHeight; y++)
    {
      paddedScaledIcon->setPixel(x,y, qRgba(255, 255, 255,0) );
    }
  }

  //paint image in center of padded region
  int xDiff = idealImageWidth - actualImageWidth;
  int yDiff = idealImageHeight  - actualImageHeight;
  int x2 = 0;
  for(x= xDiff/2; x < (xDiff/2) + actualImageWidth; x++)
  {
    int y2 = 0;
    for(y= yDiff/2; y < (yDiff/2) + actualImageHeight; y++)
    {
      paddedScaledIcon->setPixel(x, y, scaledIcon.pixel(x2, y2));
       y2++;
    }
    x2++;
  }

  //clip corners if image takes up full width
  if(xDiff == 0)
  {
      paddedScaledIcon->setPixel(0, 0, qRgba(255, 0,0,0) );
      paddedScaledIcon->setPixel(idealImageWidth-1, 0, qRgba(255, 0,0,0) );
      paddedScaledIcon->setPixel(0, idealImageHeight-1, qRgba(255, 0,0,0) );
      paddedScaledIcon->setPixel(idealImageWidth-1, idealImageHeight-1, qRgba(255, 0,0,0) );
  }

  QPixmap* padddedScaledPix = new QPixmap( paddedScaledIcon->width(), paddedScaledIcon->height() );
  padddedScaledPix->convertFromImage( *paddedScaledIcon );
  delete paddedScaledIcon;
  return padddedScaledPix;
 //----------------------------------------------
}
//==============================================
void SubalbumPreviewWidget::calcRect( const QString & text_ )
{  
  //setup default dimensions
  QIconViewItem::calcRect( text_ );  

  //update using init method
  initializeItemRect();
}  
//==============================================
void SubalbumPreviewWidget::initializeItemRect()
{
  //reset pixmap rect
  QRect pr = pixmapRect();
  int prWidth  = pr.width();
  int prHeight = pr.height();
  pr.setTopLeft( QPoint(3,3) );
  pr.setBottomRight( QPoint(pr.left()+prWidth, pr.top()+prHeight) );
  setPixmapRect( pr );
  
  //reset text rect
  int textWidth = parent->getTextWidth();
  QRect tr = textRect();
  tr.setTop( pixmapRect().top() );
  tr.setBottom( pixmapRect().bottom() );
  tr.setLeft( pixmapRect().right() + 2 );
  tr.setRight( tr.left() + textWidth );
  setTextRect( tr );
  
  //reset item rect using pixmap and text rect dimensions
  int itemW = 3 + pixmapRect().width() + (tr.left() - pr.right()) + textRect().width() + 3;
  int itemH = 3 + pixmapRect().height() + 3;
  setItemRect( QRect( pixmapRect().left() - 3, pixmapRect().top() - 3, itemW, itemH ) );
}
//==============================================
void SubalbumPreviewWidget::setText ( const QString & text )
{
  QIconViewItem::setText( clipText(text, 2, parent->getTextWidth()), false );
}
//==============================================
void SubalbumPreviewWidget::setMousedOver(bool val)
{
  mousedOver = val;
}
//==============================================
QColor SubalbumPreviewWidget::blendColors( QColor a, QColor b, double alpha)
{
  double alpha2 = 1-alpha;
  return QColor( (int)(alpha*a.red() + alpha2*b.red()),
                          (int)(alpha*a.green() + alpha2*b.green()),
                          (int)(alpha*a.blue() + alpha2*b.blue()) );
}
//==============================================
