#include "otherviewWidget.h"
#include <cassert>
#include <iostream>
#include <qpainter.h>
#include <qstyle.h>
#include <qrect.h>
#include <qpalette.h>
#include <algorithm>
#include "../../streams/ErrorStream.h"
extern ExceptionStream< ostream&, ContinueFunctor  >		KODIAK_WARNING;
extern KODIAK_DEBUG_STREAM KODIAK_DEBUG_COUT;

OtherviewWidget::OtherviewWidget(  QWidget *parent ): QGroupBox( parent)
{
	this->ui_.setupUi( this );

	this->activeObjectPicture = new MyPushButton( 0, this->ui_.damageStatusFrame_5 );
	this->activeObjectPicture->setGeometry( 0,0, this->ui_.damageStatusFrame_5->width(), this->ui_.damageStatusFrame_5->height() );
	bool ok;

	// lifeLabel
	ok = QObject::connect(	this, SIGNAL(setLifeSignal( unsigned int ) ),
							this->ui_.lifeLabel, SLOT( progressSlot(unsigned int)));
	// shieldLabel
	ok = ok &&  QObject::connect(	this, SIGNAL(setShieldSignal( unsigned int ) ),
									this->ui_.shieldLabel, SLOT( progressSlot(unsigned int)));
	
	// warpBox
	ok = ok &&  QObject::connect(	this->ui_.warpBox, SIGNAL( stateChanged ( int )),
									this, SLOT( setWarpSlot( int )));
	
	// ignationBox
	//ok = ok &&  QObject::connect(	this->ui_.ignationBox, SIGNAL(valueChanged ( double ) ),
	//								this, SLOT( setIgnationTimeSlot(double)));

	ok = ok &&  QObject::connect(	this->ui_.applyButton, SIGNAL(clicked () ),
									this, SLOT( setIgnationTimeSlot()));

	// shipSelectionWidget item
	this->shipSelectionWidget = new SelectionWidget( this->ui_.shipSelectionPanel );
	this->shipSelectionWidget->init( 7 ); //max 7 buttons

	assert( ok && "Connection failed!" );
}


void OtherviewWidget::setLifeSlot( unsigned int percentage )
{
	emit this->setLifeSignal( percentage );
}

void OtherviewWidget::setShieldSlot( unsigned int percentage )
{
	emit this->setShieldSignal( percentage );
}
void OtherviewWidget::setWarpSlot( int useWarp )
{
	emit this->setWarpSignal( useWarp );
}
void OtherviewWidget::setIgnationTimeSlot( void )
{
	int daysVal = this->ui_.daysBox->value();
	int hoursVal = this->ui_.hoursBox->value();
	int minutesVal = this->ui_.minutesBox->value();
	int secondsVal = this->ui_.secondsBox->value();

	double ignationTime = daysVal + dv_time::encodeTime( hoursVal, minutesVal, secondsVal, 0 );
	emit this->setIgnationTimeSignal( ignationTime );
}

void OtherviewWidget::setActiveObject( const QIcon & iconPicture, const QString &text, unsigned long slotIdx )
{
	if ( this->activeObjectPicture == NULL ) return;

	QSize size( 90, 70 );	// max picture size limits!!!
	iconPicture.actualSize( size );

	this->activeObjectPicture->setIconSize(size);
	this->activeObjectPicture->setIcon(iconPicture);
	this->activeObjectPicture->myText = text;
	this->activeObjectPicture->slotIdx = slotIdx;
}

MyPushButton*  OtherviewWidget::getShipSlot( unsigned int id )
{
	if ( this->shipSelectionWidget == NULL ) return NULL;
	
	if ( id >= this->shipSelectionWidget->getArraySize() )
	{
		//out of range
		KODIAK_WARNING<<"otherviewWidget::getShipSlot: Out of range -> ignored";
		return NULL;
	}

	return &this->shipSelectionWidget->getItem( id );
}

const SelectionWidget * OtherviewWidget::getShipSelectionWidget( void )
{
	return this->shipSelectionWidget;
}



//######################################################################

SelectionLogic::SelectionLogic( OtherviewWidget &otherviewWidget ): otherviewWidget( otherviewWidget )
{
	

	this->activeSlotIdx = -1; //no active slot

	bool ok;
	ok =  QObject::connect( otherviewWidget.getShipSelectionWidget(), SIGNAL(  selectedItem( unsigned int ) ), this, SLOT( selectedShipSlot( unsigned int ) ) );
	ok =  ok && QObject::connect( otherviewWidget.activeObjectPicture, SIGNAL(  clickedSignal( unsigned int ) ), this, SLOT( selectedShipSlot( unsigned int ) ) );
	
	ok =  ok && QObject::connect( otherviewWidget.ui_.microMacroButton, SIGNAL(  clicked() ), this, SLOT( microMacroButtonSlot() ) );
	ok =  ok && QObject::connect( otherviewWidget.ui_.attackButton, SIGNAL(  clicked() ), this, SLOT( attackButtonSlot() ) );
	ok =  ok && QObject::connect( otherviewWidget.ui_.radarButton, SIGNAL(  clicked() ), this, SLOT( radarButtonSlot() ) );
	ok =  ok && QObject::connect( otherviewWidget.ui_.settingsButton, SIGNAL(  clicked() ), this, SLOT( settingsButtonSlot() ) );
	ok =  ok && QObject::connect( otherviewWidget.ui_.navigationButton, SIGNAL(  clicked() ), this, SLOT( navigationButtonSlot() ) );
	ok =  ok && QObject::connect( otherviewWidget.ui_.weaponsButton, SIGNAL(  clicked() ), this, SLOT( weaponsButtonSlot() ) );

	ok =  ok && QObject::connect( &otherviewWidget, SIGNAL(   setIgnationTimeSignal ( double  )), this, SLOT( ignationChangedSlot( double)));
	ok =  ok && QObject::connect( &otherviewWidget, SIGNAL(   setWarpSignal ( bool  )), this, SLOT( warpChangeSlot( bool)));

	assert( ok && "QObject connection failed!" );

	//sets all slot to be free
	for ( int i=0; i < SelectionLogic::ARRAY_SIZE; ++i)
	{
		this->shipIdArray[ i].shipId = 0;  
		//this->shipIdArray[ i].shipName ="";
	}


	this->ignationTimeSec = 0;
	otherviewWidget.setIgnationTimeSlot();
	this->useWarp =  otherviewWidget.ui_.warpBox->isChecked();
}
bool SelectionLogic::insertShip(  unsigned long shipId, const string &shipName, ShipType shipType  )
{
	//search up for first free cell in array
	for ( int i=0; i < SelectionLogic::ARRAY_SIZE; ++i)
	{
		
		if ( this->shipIdArray[ i].shipId == 0 )   //position is free
		{
			this->shipIdArray[i].shipId = shipId;
			//this->shipIdArray[i].shipName = shipName;

			this->otherviewWidget.getShipSlot( i )->myText= shipName.c_str();
			this->otherviewWidget.getShipSlot( i )->setIconSize( QSize(25,25));
			this->otherviewWidget.getShipSlot( i )->setIcon( this->shipIcon[ shipType ].smallIcon );
			
			return true; //insertion OK
		}
	}

		//std::cout<<" insertion KO";
	return false; // insertion failed, no free cell
}
bool SelectionLogic::getShipId( unsigned int idx, unsigned long &dstShipId)
{
	//assert( idx < SelectionLogic::ARRAY_SIZE && "Out of range" );
	if ( idx >= SelectionLogic::ARRAY_SIZE ) 
	{
		return false;
	}

	dstShipId = this->shipIdArray[ idx ].shipId;

	return true; 
}
void SelectionLogic::refreshShipState( ShipType shipType, unsigned int lifePercentage, unsigned int shieldPercentage, const QString& shipName)
{
	if ( this->activeSlotIdx < 0 ) return;

	//unsigned long activeShipId = 0;
	//this->getShipId( this->activeSlotIdx, activeShipId );

	this->otherviewWidget.setActiveObject( this->shipIcon[ shipType ].bigIcon, shipName, this->activeSlotIdx );
	this->otherviewWidget.setLifeSlot( lifePercentage );
	this->otherviewWidget.setShieldSlot( shieldPercentage );

}
bool SelectionLogic::isFullShipArray( void )
{
	//search up for first free cell in array
	for ( int i=0; i < SelectionLogic::ARRAY_SIZE; ++i)
	{
		if ( this->shipIdArray[ i].shipId == 0 )   //position is free
		{
			return false; //is not full
		}
	}

	return true; //is full
}
void SelectionLogic::removeShip( unsigned int idx )
{
	//assert( idx < SelectionLogic::ARRAY_SIZE &&"Out of range" );
	if ( idx >= SelectionLogic::ARRAY_SIZE ) 
	{
		KODIAK_WARNING<<"SelectionLogic::removeShip: No ship in slot idx: "+intToString(idx);
		return ;
	}


	this->shipIdArray[ idx ].shipId = 0; //mark cell as free
	this->otherviewWidget.getShipSlot( idx )->myText.clear(); //no text
	this->otherviewWidget.getShipSlot( idx )->setIcon( QIcon() ); //no icon
}
void SelectionLogic::clearShips(void)
{
	for ( int i=0; i< ARRAY_SIZE; ++i)
	{
		this->shipIdArray[ i ].shipId = 0; //mark cell as free
		this->otherviewWidget.getShipSlot( i )->setIcon( QIcon() ); //no icon
		this->otherviewWidget.getShipSlot( i )->myText.clear(); //no text
	}
}

void SelectionLogic::selectedShipSlot( unsigned int idx, bool callSelectionCallback )
{
	if ( idx < ARRAY_SIZE && this->shipIdArray[ idx ].shipId == 0 )
	{
		//if slot does not contain any valid shipId then ignore
		return;
	}

	this->activeSlotIdx = idx;

	if ( callSelectionCallback )
	{
		assert( this->newSelectionCallback );
		this->newSelectionCallback( idx );
	}

}

void SelectionLogic::microMacroButtonSlot( void)
{
	assert( this->newMacroMicroCallback );
	this->newMacroMicroCallback();
}

void SelectionLogic::attackButtonSlot(void)
{
	unsigned long activeShipId = 0;
	bool ok = this->getShipId( this->activeSlotIdx, activeShipId);

	if ( !ok )
	{
		KODIAK_WARNING<<"otherviewWidget::attackButtonSlot: Out of range -> ignored";
		return;
	}

	emit attackButtonSignal( activeShipId  );
}
void SelectionLogic::radarButtonSlot(void)
{
	unsigned long activeShipId = 0;
	bool ok = this->getShipId( this->activeSlotIdx, activeShipId);

	if ( !ok )
	{
		KODIAK_WARNING<<"otherviewWidget::radarButtonSlot: Out of range -> ignored";
		return;
	}

	emit radarButtonSignal( activeShipId );

	assert( this->newRadarCallback );
	this->newRadarCallback();
}

void SelectionLogic::settingsButtonSlot(void)
{
	unsigned long activeShipId = 0;
	bool ok = this->getShipId( this->activeSlotIdx, activeShipId);

	if ( !ok )
	{
		KODIAK_WARNING<<"otherviewWidget::settingsButtonSlot::getShipSlot: Out of range -> ignored";
		return;
	}

	emit settingButtonSignal( activeShipId );
}

void SelectionLogic::navigationButtonSlot(void)
{
	unsigned long activeShipId = 0;
	bool ok = this->getShipId( this->activeSlotIdx, activeShipId);

	if ( !ok )
	{
		KODIAK_WARNING<<"otherviewWidget::navigationButtonSlot::getShipSlot: Out of range -> ignored";
		return;
	}

	emit navigationButtonSignal( activeShipId );
}

void SelectionLogic::weaponsButtonSlot(void)
{
	unsigned long activeShipId = 0;
	bool ok = this->getShipId( this->activeSlotIdx, activeShipId);

	if ( !ok )
	{
		KODIAK_WARNING<<"otherviewWidget::weaponsButtonSlot::getShipSlot: Out of range -> ignored";
		return;
	}

	emit weaponsButtonSignal( activeShipId );
}

void SelectionLogic::ignationChangedSlot( double dayLimit )
{
	this->ignationTimeSec = dayLimit * 24 * 60 * 60;
}

void SelectionLogic::warpChangeSlot( bool useWarp )
{
	this->useWarp = useWarp;
}