/*
 * Copyright 2009-2010  Stefan Gehn <stefan@srcbox.net>
 * 
 * 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.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "PhotoPage.hpp"
#include "PhotoPageWidgets.hpp"
#include "PhotoDraggable.hpp"

#include <qbrush.h>
#include <qdebug.h>
#include <qmenu.h>
#include <qpainter.h>
#include <qstyleoption.h>
#include <qgraphicsgridlayout.h>

#define PAGE_MARGIN 30


PhotoPage::PhotoPage(QGraphicsItem *parent): QGraphicsWidget(parent),	mPageIndex(0)
{
	//qDebug() << "PhotoPage::PhotoPage(); this:" << (QGraphicsItem *)this;

	// Grauer Hintergrund
	palette().setColor(QPalette::Window, QColor(240, 240, 240));
	// Dunkelgrauer Seitenrand
	palette().setColor(QPalette::WindowText, QColor(96, 96, 96));

	QGraphicsGridLayout *l = new QGraphicsGridLayout(this);
	l->setSpacing(0);
	l->setContentsMargins(1, 1, 1, 1);
	l->setColumnFixedWidth(0, PAGE_MARGIN);
	l->setColumnFixedWidth(2, PAGE_MARGIN);
	l->setRowFixedHeight(0, PAGE_MARGIN);
	l->setRowFixedHeight(2, PAGE_MARGIN);

	mContentRect = new RectWidget(this);
	l->addItem(mContentRect, 1, 1);

	mLeftEdgeWidget = new EdgeWidget(EdgeWidget::Left, this);
	connect(mLeftEdgeWidget, SIGNAL(activated()), this, SIGNAL(turnPage()));
	l->addItem(mLeftEdgeWidget, 2, 0);

	mPageNumberWidget = new NumberWidget(this);
	l->addItem(mPageNumberWidget, 2, 1);

	mRightEdgeWidget = new EdgeWidget(EdgeWidget::Right, this);
	connect(mRightEdgeWidget, SIGNAL(activated()), this, SIGNAL(turnPage()));
	l->addItem(mRightEdgeWidget, 2, 2);

	QAction *clearAction = new QAction(tr("Seiteninhalt löschen"), this);
	connect(clearAction, SIGNAL(triggered()), this, SLOT(clearPage()));
	addAction(clearAction);

  setAcceptedMouseButtons(Qt::LeftButton);
}

PhotoPage::~PhotoPage()
{
  //
}

void PhotoPage::addDraggable(PhotoDraggable *draggable)
{
  if (draggable && draggable->parentWidget() != mContentRect)
  {
    draggable->reparent(mContentRect);
    draggable->setEnabled(false); // photos on a page are not editable
  }
}

void PhotoPage::removeDraggable(PhotoDraggable *draggable)
{
  if (draggable && draggable->parentWidget() == mContentRect)
  {
    draggable->reparent(0L);
    draggable->setEnabled(true);
  }
}

void PhotoPage::clearPage()
{
  Q_FOREACH(QGraphicsItem *item, mContentRect->childItems())
  {
    PhotoDraggable *draggable = dynamic_cast<PhotoDraggable *>(item);
    if (!draggable)
      continue;
		draggable->deleteLater();
  }
}

void PhotoPage::paint(QPainter *painter,
    const QStyleOptionGraphicsItem *option,
    QWidget *widget)
{
  Q_UNUSED(widget);
  Q_UNUSED(option);

  painter->setClipRect(option->exposedRect);
  painter->setBrush(palette().window());
  painter->setPen(QPen(palette().windowText(), 1, Qt::SolidLine));

  qreal w = size().width();
  qreal h = size().height();
  qreal halfPenW = painter->pen().widthF() / 2;

	if ((mPageIndex % 2) == 0)
	{ // linke seite
		QPointF points[6] = {
			QPointF(halfPenW, 0),
			QPointF(w - PAGE_MARGIN, 0),
			QPointF(w - halfPenW, (PAGE_MARGIN/2)),
			QPointF(w - halfPenW, h - (PAGE_MARGIN/2)),
			QPointF(w - PAGE_MARGIN, h - halfPenW),
			QPointF(halfPenW, h - halfPenW) };
    painter->drawPolygon(points, 6);
	}
  else
  {
		QPointF points[6] = {
			QPointF(halfPenW, (PAGE_MARGIN/2)),
			QPointF(PAGE_MARGIN, 0),
			QPointF(w - halfPenW, 0),
			QPointF(w - halfPenW, h - halfPenW),
			QPointF(PAGE_MARGIN, h - halfPenW),
			QPointF(halfPenW, h - (PAGE_MARGIN/2) - halfPenW) };
    painter->drawPolygon(points, 6);
	}
}

void PhotoPage::setPageIndex(int pageIndex, int pageCount)
{
	//qDebug() << "PhotoPage::setPageIndex(); pageIndex:" << pageIndex << "; pageCount:" << pageCount;
	static_cast<NumberWidget*>(mPageNumberWidget)->setNumber(pageIndex + 1);
	bool showLeft  = (pageIndex != 0) && !(pageIndex % 2);
	bool showRight = (pageIndex != pageCount - 1) && (pageIndex % 2);
	mLeftEdgeWidget->setVisible(showLeft);
	mRightEdgeWidget->setVisible(showRight);
	mPageIndex = pageIndex;
	update();
}

void PhotoPage::contextMenuEvent(QGraphicsSceneContextMenuEvent * event)
{
	QMenu contextMenu;
	event->accept();
	contextMenu.addActions(actions());
	contextMenu.exec(event->screenPos());
}

QDataStream & operator<< (QDataStream &stream, const PhotoPage &page)
{
  QList <const PhotoDraggable *> draggablesList;

  // find all draggables, we need to know the count before serializing them
  Q_FOREACH(const QGraphicsItem *item, page.mContentRect->childItems())
  {
    const PhotoDraggable *draggable = dynamic_cast<const PhotoDraggable *>(item);
    if (!draggable)
      continue;
    draggablesList.append(draggable);
  }

  // save number of photos to stream
  stream << draggablesList.count();

  // save photo properties to stream
  Q_FOREACH(const PhotoDraggable *draggable, draggablesList)
  {
    stream << *draggable;
  }

  return stream;
}


QDataStream & operator>> (QDataStream &stream, PhotoPage &page)
{
  int numDraggables;

  // Read number of photos from stream
  stream >> numDraggables;

  // Read photo properties from stream and create draggables accordingly
  while (numDraggables--)
  {
    PhotoDraggable *dr = new PhotoDraggable();
    stream >> *dr;
    page.addDraggable(dr);
  }

  return stream;
}

#include "moc_PhotoPage.cpp"
