/*************************************************************************\
*   Copyright (C) 2009 by Ulf Kreissig                                    *
*   udev@gmx.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, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
\*************************************************************************/

#ifndef YAWP_PANEL_LAYOUT_H
#define YAWP_PANEL_LAYOUT_H

//--- LOCAL CLASSES ---
#include "yawpdefines.h"

//--- QT4 CLASSES ---
#include <QRectF>
#include <QSizeF>

//--- KDE4 CLASSES ---
#include <Plasma/Applet>

/**  This classes will calculate certain rectangles/areas we use in YaWP to paint
*    the icons/temperatures and so on.
*    This makes the YaWP class better readable and in some function we take some benefit of
*    the abstract interface of all this layout-classes.
*/
class AbstractPanelLayout
{
public:
	AbstractPanelLayout();
	virtual ~AbstractPanelLayout();

	virtual Plasma::FormFactor form() const = 0;

	virtual void		setContentsRect( const QRectF & rect )    { m_contentsRect = rect; }
	inline QRectF		contentsRect() const                      { return m_contentsRect; }
	void				setTodaysFormat( Yawp::PanelDayFormat format )  { m_tTodaysFormat = format; }
	inline Yawp::PanelDayFormat	todaysFormat() const                      { return m_tTodaysFormat; }
	void				setForecastFormat( Yawp::PanelDayFormat format ){ m_tForecastFormat = format; }
	inline Yawp::PanelDayFormat	forecastFormat() const                    { return m_tForecastFormat; }
	void				setForecastDays( const int days )         { m_iForecastDays = days; }
	inline int			forecastDays() const                      { return m_iForecastDays; }
	
	inline bool			useCompactLayout() const {return m_bUseCompactLayout;}
	void				setUseCompactLayout(bool bCompact) { m_bUseCompactLayout = bCompact; }

	virtual qreal			getScalingFactor() const = 0;

	virtual QSizeF			getSize( const QSizeF & size = QSizeF() ) const = 0;
	virtual QRectF			getTodaysTempRect() const = 0;
	virtual QRectF			getTodaysIconRect() const = 0;
	virtual QRectF			getForecastTempRect( const int iDay ) const = 0;
	virtual QRectF			getForecastIconRect( const int iDay ) const = 0;

private:	
	QRectF				m_contentsRect;
	int					m_iForecastDays;
	Yawp::PanelDayFormat		m_tTodaysFormat;
	Yawp::PanelDayFormat		m_tForecastFormat;
	bool			m_bUseCompactLayout;
};


class HorizontalPanelLayout	: public AbstractPanelLayout
{
public:
	HorizontalPanelLayout();
	~HorizontalPanelLayout();

	virtual void		setContentsRect( const QRectF & rect );
	Plasma::FormFactor	form() const { return Plasma::Horizontal; }

	qreal				getScalingFactor() const;
	QSizeF				getSize( const QSizeF & size = QSizeF() ) const;

	QRectF				getTodaysTempRect() const;
	QRectF				getTodaysIconRect() const;
	QRectF				getForecastTempRect( const int iDay ) const;
	QRectF				getForecastIconRect( const int iDay ) const;

private:
	float				calculateTodaysOffset() const;
	float				getTemperatureWidth( int iPixelSize, const QString & str = QString("-99")+QChar(0xB0) ) const;
	
	float	m_dTodaysTempWidth;
	float	m_dForecastTempWidth;
};


class VerticalPanelLayout	: public AbstractPanelLayout
{
public:
	VerticalPanelLayout();
	~VerticalPanelLayout();

	Plasma::FormFactor		form() const { return Plasma::Vertical; }

	qreal				getScalingFactor() const;
	QSizeF				getSize( const QSizeF & size = QSizeF() ) const;

	QRectF				getTodaysTempRect() const;
	QRectF				getTodaysIconRect() const;
	QRectF				getForecastTempRect( const int iDay ) const;
	QRectF				getForecastIconRect( const int iDay ) const;

private:
	float				calculateTodaysOffset() const;
	QRectF				getCompactIconRect(int index) const;
	QRectF				getCompactTempRect(int index) const;
};


class DesktopLayout	: public AbstractPanelLayout
{
public:
	DesktopLayout();
	~DesktopLayout();

	Plasma::FormFactor		form() const                                     { return Plasma::Planar; }

	void				setContentsRect( const QRectF & rect );
	qreal				getScalingFactor() const                         { return m_dScale; }
	QSizeF				getSize( const QSizeF & size = QSizeF() ) const;
	QRectF				getPageRect() const;

	QRectF				getCurrentTempRect() const;
	QRectF				getSateliteRect() const;

	QRectF				getTodaysTempRect() const;
	QRectF				getTodaysIconRect() const;

	/**  The details rectange describes the entire place where
	*    the daynames and the weather forecast will be placed.
	*/
	QRectF				getDetailsRect() const;

	/**  When we draw on the PageAnimator for Animationeffekts whe have to use a
	*    different start-possition then we use to draw on the desktop.
	*    So we save this certain rectangle also in this class, since the following function
	*    depending on the details rectangle.
	*    In order to use this functions, you have to set the userDefinedDetailsRect.
	*/
	void				setUserDefinedDetailsRect( const QRectF & rect ) { m_detailsRect = rect; }
	QRectF				getUserDefinedDetailsRect() const                { return m_detailsRect; }

	QRectF				getForecastDayNamesRect() const;
	QRectF				getDetailsArrowRect( const bool bForward ) const;
	QRectF				getForecastTempRect( const int iDay ) const;
	QRectF				getForecastIconRect( const int iDay ) const;

private:
	float				m_dScale;
	QRectF				m_detailsRect;
};

#endif // YAWP_PANEL_LAYOUT_H
