/***************************************************************************
 *   Copyright (C) 2004 by Stefano                                         *
 *   stefano@xiaprojects.com                                               *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "xematrix.h"
#include "xeobject.h"
#include "xeconfiguration.h"
#include "xgdocker.h"
#include "xgicon.h"

#include <stdlib.h>
#include <stdio.h>

XEMatrix::XEMatrix(QObject *parent, const char *name)
 : QObject(parent, name)
{
	XEObject::xSetEngineMatrix(this);
}


XEMatrix::~XEMatrix()
{
}


#include "xematrix.moc"


/*!
    \fn XEMatrix::xSetup()
 */
void XEMatrix::xSetup()
{
	// Query for last configuration
	XEConfiguration *Configurator=(XEConfiguration *)XEObject::xGetConfiguration();
	xGDocker=(XGDocker *)XEObject::xGetDocker();
	if(Configurator==NULL || xGDocker==NULL)
	{
#ifndef ENABLE_FINAL
	// Emits Signal of warning
	xWarningMsg(this,"error while searching for plugin");
#endif
		return;
	}
	ActiveConfiguration=Configurator->xGetConfiguration();
	xMake(ActiveConfiguration->Matrix.Design);
}


/*!
    \fn XEMatrix::xMake(const QString &)
 */
void XEMatrix::xMake(const QString &newDesign)
{
	if(ActiveConfiguration==NULL)
	{
#ifndef ENABLE_FINAL
	// Emits Signal of warning
	xWarningMsg(this,"error while searching for configuration data");
#endif
		return;
	}
	if(newDesign=="realosx")
	{
		ActiveConfiguration->Matrix.DesignXMoltiplier=1;
		ActiveConfiguration->Matrix.DesignYMoltiplier=1;
		ActiveConfiguration->Matrix.DesignDMoltiplier=3;
		xMakeRealOSX();
	}
	if(newDesign=="osxbar")
	{
		ActiveConfiguration->Matrix.DesignXMoltiplier=1;
		ActiveConfiguration->Matrix.DesignYMoltiplier=1;
		ActiveConfiguration->Matrix.DesignDMoltiplier=1;
		xMakeRealOSX();
	}
}


/*!
    \fn XEMatrix::MakeCenter(int iconIndex, QPoint *xy)
 */
void XEMatrix::xMakeCenter(int iconIndex, QPoint *xy)
{
	/// @todo implement me
	xMakeSpace(iconIndex,xy);
	xy->setX(xy->x()+ActiveConfiguration->Icons.Size/2);
	xy->setY(xy->y()+ActiveConfiguration->Icons.Size/2+ActiveConfiguration->Icons.Raise);
}

/*!
    \fn XEMatrix::xMakeSpace(int iconIndex, QPoint *xy)
 */
void XEMatrix::xMakeSpace(int iconIndex, QPoint *xy)
{
	/// @todo implement me
	xy->setX(
			ActiveConfiguration->Window.borderLeft
			+
			(iconIndex*
				(ActiveConfiguration->Icons.Separation+ActiveConfiguration->Icons.Size)
				));
	xy->setY(
			ActiveConfiguration->Window.borderTop);

}

/*!
    \fn XEMatrix::xCfgChanged(QObject *newConf)
 */
void XEMatrix::xCfgChanged(QObject *newConf)
{

	XEConfiguration *NewConfigurator=(XEConfiguration *)newConf;
	if(NewConfigurator==NULL)
	{
#ifndef ENABLE_FINAL
	// Emits Signal of warning
	xWarningMsg(this,"falling back to ActiveConfiguration");
#endif
		// return;
	}
	else
	{
		ActiveConfiguration=NewConfigurator->xGetConfiguration();
	}
	if(ActiveConfiguration==NULL)
	{
#ifndef ENABLE_FINAL
	// Emits Signal of warning
	xWarningMsg(this,"error while searching for configuration data");
#endif
		return;
	}
#ifndef ENABLE_FINAL
	// Emits Signal of warning
	xWarningMsg(this,"appling new configuration");
#endif
	
	xMake(ActiveConfiguration->Matrix.Design);
}




/*!
    \fn XEMatrix::xMakeBarSpace(int)
 */
void XEMatrix::xMakeBarSpace(int part, QPoint *xy)
{
	
		if(part==0)
		{
			xy->setX(
				xGDocker->getObjectIcon(0)->xPosDefault.x()-
				ActiveConfiguration->Icons.Size
				-16
				);
		
			xy->setY(xGDocker->getObjectIcon(0)->xPosDefault.y()-8);
		}
		else if(part==1)
		{
			xy->setX(xGDocker->getObjectIcon(0)->xPosDefault.x());
			xy->setY(xGDocker->getObjectIcon(0)->xPosDefault.y()-8);
		}
		else if(part==2)
		{
			/*
			xy->setX(xGDocker->getObjectIcon(icon)->xPosDefault.x());
			xy->setY(xGDocker->getObjectIcon(icon)->xPosDefault.y()-8);
			
			lasticonidx=len(self.Engine.Objects)-1
			x=self.Engine.Objects[lasticonidx].currentX+self.Engine.Objects[lasticonidx].currentZ+self.Engine.Configuration["iconSeparation"]
			y=self.Engine.Objects[0].defaultY-8
			*/
		}

		return;
}


/*!
    \fn XEMatrix::xMakeRealOSX();
 */
void XEMatrix::xMakeRealOSX()
{
	double ratio=0;
	double ratioy=0;
	double ratiod=0;
	double kappa=0;
	
	
	QPoint p1,p2;
		// this will create the rights matrix :)
		// I hope!
		
		// the size of the matrix depend on how much far the icons must animate
		// for example on osx we manage the distance from big icons
		// *2 because is from left to right
		// int
		ActiveConfiguration->Matrix.sizeMatrix=(
			ActiveConfiguration->Icons.Size + ActiveConfiguration->Icons.Separation
			)*2;
		// ratio:
		// quantum icon size step
		// double
		ratio=double(ActiveConfiguration->Icons.SizeBig-ActiveConfiguration->Icons.Size)
				/
				double(ActiveConfiguration->Matrix.sizeMatrix*2);
		// This function will align the icons
		// now we have to get the Y displacement
		xMakeCenter(0,&p1);
		xMakeCenter(0,&p2);
		// quantum icon must raise
		// double
		ratioy=(-double(ActiveConfiguration->Icons.Raise)/double(ActiveConfiguration->Matrix.sizeMatrix*2));
		// horizontal displacement
		// double
		ratiod=(double(ActiveConfiguration->Icons.Horiz)/double(ActiveConfiguration->Matrix.sizeMatrix*2));
		
		// TODO: garbage on reloadig matrix
		// Allocate arrays
		ActiveConfiguration->Matrix.XMatrix=
			new int[ActiveConfiguration->Matrix.sizeMatrix*2];
		ActiveConfiguration->Matrix.YMatrix=
			new int[ActiveConfiguration->Matrix.sizeMatrix*2];
		ActiveConfiguration->Matrix.ZMatrix=
			new int[ActiveConfiguration->Matrix.sizeMatrix*2];

		// loadin static matrix
		// simulating the mouse movement from - infite to + infinite relative to 1 icon
		for (int mouseinx=0;mouseinx<ActiveConfiguration->Matrix.sizeMatrix*2;mouseinx++)
		{
			// 14052004
			// precision variables
			// int -> double <-
			double ZMatrixDouble=double(ActiveConfiguration->Icons.SizeBig)-double(ratio*mouseinx);
			ActiveConfiguration->Matrix.ZMatrix[mouseinx]=(int)ZMatrixDouble;
				
			ActiveConfiguration->Matrix.YMatrix[mouseinx]=(int)
				double(
				ZMatrixDouble/2
				+double(ActiveConfiguration->Matrix.sizeMatrix*2 -mouseinx) * ratioy
				-double(ActiveConfiguration->Icons.Size/2));
			ActiveConfiguration->Matrix.XMatrix[mouseinx]=(int)
				double(ZMatrixDouble/2
				-double(ActiveConfiguration->Icons.Size/2));
		}
		
		// dynamic horizontal displacement
		ActiveConfiguration->Matrix.DMatrix=
			new int*[ActiveConfiguration->Matrix.sizeMatrix*2];
		
		for (int mouseinx=0;mouseinx<ActiveConfiguration->Matrix.sizeMatrix*2;mouseinx++)
		{
			int *vett=new int[ActiveConfiguration->Matrix.sizeMatrix*2];
			
			for(int mouseiny=0;mouseiny<ActiveConfiguration->Matrix.sizeMatrix*2;mouseiny++)
			{
				kappa=
					double(ActiveConfiguration->Matrix.ZMatrix[mouseinx/2+mouseiny/2]*3)
					/double(ActiveConfiguration->Icons.SizeBig);
				kappa=kappa*double(ActiveConfiguration->Matrix.DesignDMoltiplier);
				vett[mouseiny]=int((ratiod*mouseinx*kappa));

			}
			ActiveConfiguration->Matrix.DMatrix[mouseinx]=vett;
		}
		
		ActiveConfiguration->Matrix.KMatrix=new int[ActiveConfiguration->Matrix.sizeMatrix*2];

		/*
		char riga[50];
		for (int mouseinx=0;mouseinx<ActiveConfiguration->Matrix.sizeMatrix*2;mouseinx++)
		{
			for (int mouseiny=0;mouseiny<ActiveConfiguration->Matrix.sizeMatrix*2;mouseiny++)
			{
sprintf(riga,"DActiveConfiguration->Matrix [%d][%d]=%d",mouseinx,mouseiny,ActiveConfiguration->Matrix.DMatrix[mouseinx][mouseiny]);
//				qWarning(riga);
		}}
		*/
		
		double ratiok=
			double(ActiveConfiguration->Matrix.DMatrix[ActiveConfiguration->Matrix.sizeMatrix*2-1][0])
			/double(ActiveConfiguration->Matrix.sizeMatrix*2);
		for (int mouseinx=0;mouseinx<ActiveConfiguration->Matrix.sizeMatrix*2;mouseinx++)
		{
			ActiveConfiguration->Matrix.KMatrix[mouseinx]=int(
				ratiok*
				double(ActiveConfiguration->Matrix.sizeMatrix*2-mouseinx));
		}
}
