//****************************************************************************
//Copyright (C) 2005-2006 Beijing BlueDJ Technology Co.,Ltd. All rights reserved.

//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 (in the file LICENSE.GPL); if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

//Please visit http://www.bluedj.com for more infomation about us.
//Contact us at ggwizard@gmail.com or darkdong@gmail.com.
//****************************************************************************/

#include "DJGameController.h"
#include "DJClientRequest.h"
#include "DJGameUser.h"
#include "DJGameRoom.h"
#include "Utility.h"
#include "DJGameImage.h"
#include "DJGameTraceManager.h"
#include "protocol.h"
#include "DJAutoDisappearText.h"
#include "DJGameDesktop.h"
#include "DJShowView.h"
#include "DJMatrixCanvasImage.h"
#include "DJMatrixCanvasText.h"
#include "DJMatrixCanvasTimer.h"
#include "DJMatrixCanvasSprite.h"
#include "DJWidget.h"

static double Z_NAME	= 2000;
static double Z_CLOCK	= 3000; 
static double Z_HOST	= 1000;
static double Z_AUTO_DISAPPEAR_TEXT	= 4000;

DJGameDesktop::DJGameDesktop(QWidget* parent,DJGamePanel *panel,quint32 w,quint32 h)
 	:Q3CanvasView(parent)
{
	Q3Canvas* canvas	= new Q3Canvas( this );
	canvas->setAdvancePeriod(500);
	//canvas->setUpdatePeriod(500);
	canvas->resize( w, h ); 
	setCanvas( canvas ); 
	
	c_Panel = panel;
	c_RealWidth = w;
	c_RealHeight = h;

	setVScrollBarMode(AlwaysOff);
    setHScrollBarMode(AlwaysOff);
	
	m_start = new QPushButton(this);
	QPixmap	pix = QPixmap(":/BaseRes/image/desktop/pushbutton/KaiShi.png");
	m_start->setIcon( pix );
	m_start->setIconSize( pix.size() );
	m_start->adjustSize();
    //m_start->setText(tr("Start"));
	m_start->hide();
	connect(m_start,SIGNAL(clicked()),this,SLOT(ClickStart()));
	
	m_gameWaitStatus = 0;
	m_gameWaitMask = 0;
	m_gameWaitTimeout 	= 0;
	c_bSavable = false;
	c_TotalGames = 0;
	
	c_resizeTimer = new QTimer(this);
	c_resizeTimer->setInterval( 500 );
	c_resizeTimer->setSingleShot( true );
	connect(c_resizeTimer,SIGNAL(timeout()),this,SLOT(HandleResizeTimeout()));
	c_matrix.setMatrix(1.0,0,0,1.0,0,0);
	c_forTestStringWidthHeight = new Q3CanvasText(canvas);
	
	connect( this, SIGNAL(playerItemClicked(Qt::MouseButton,quint32)), c_Panel, SLOT(handlePlayerItemClicked(Qt::MouseButton,quint32)) );
	
	QColor color	=  GetSettingGameDesktopColor (c_Panel->gameController()->gameName());
	canvas->setBackgroundColor(color);
	QPalette pal = palette();
	pal.setBrush(QPalette::Background,color);
	setPalette(pal);
	
	//create show,name,clock
	QFont font;
	font.setBold( true );
	font.setPointSize( 14 );
	for ( int i = 0; i <= c_Panel->numberOfSeats(); ++i) {
		quint32 userId	=  c_Panel->userIdOfSeat( i );
		djDebug()<<"seat"<<i<<"userId"<<userId;
		DJGameUser	*user	= c_Panel->gameUser( userId );
		DJShowView	*showView	= new DJShowView( user, this );
		connect( showView, SIGNAL(rightClicked(quint32)), c_Panel, SLOT(showPlayerContextMenu(quint32)) );
		showView->hide();
		m_showViews  << showView;
		QString name;
		if ( user )
			name	= user->userName();
		DJMatrixCanvasText	*nameItem	= new DJMatrixCanvasText( canvas, name, font );
		nameItem->setZ( Z_NAME );
		nameItem->hide();
		m_nameItems  << nameItem;
	}
	
	m_clockItem 	= new DJMatrixCanvasTimer( canvas );
	m_clockItem->setZ(Z_CLOCK);
	m_clockItem->hide();
	
	m_hostItem	= new DJMatrixCanvasImage( canvas, QPixmap(":/BaseRes/image/hall/break.png") );
	m_hostItem->setZ(Z_HOST);
	m_hostItem->hide();
	
	locateShowPositions( m_showPoints, m_showAligns, m_showModes );
	djDebug()<<"DJGameDesktop::constructor"<<"m_showPoints"<<m_showPoints;
	djDebug()<<"DJGameDesktop::constructor"<<"m_showModes"<<m_showModes;
	
	locateNamePositions( m_namePoints, m_nameAligns, m_nameModes );
	djDebug()<<"DJGameDesktop::constructor"<<"m_namePoints"<<m_namePoints;
	djDebug()<<"DJGameDesktop::constructor"<<"m_nameModes"<<m_nameModes;
	
	locateClockPosition( m_clockPoint, m_clockAlign, m_clockMode );
	djDebug()<<"DJGameDesktop::constructor"<<"m_clockPoint"<<m_clockPoint;
	djDebug()<<"DJGameDesktop::constructor"<<"m_clockMode"<<m_clockMode;
	
	locateHostPositions( m_hostPoints, m_hostAligns, m_hostModes );
	djDebug()<<"DJGameDesktop::constructor"<<"m_hostPoints"<<m_hostPoints;
	djDebug()<<"DJGameDesktop::constructor"<<"m_hostModes"<<m_hostModes;
	
	m_hostEnabled	= false;
	
	m_bonusWidget	= new DJWidget( this , DJWidget::Pixmap );
		
	QVBoxLayout* layout	= new QVBoxLayout( m_bonusWidget );
	layout->setMargin( 5 );
	layout->setSpacing( 0 );
	
	pix	= QPixmap(":/BaseRes/image/bonus/background.png");
	m_bonusWidget->setPixmap( pix );
#ifndef Q_WS_MAC	
	m_bonusWidget->setFixedSize( pix.size() );
#endif

	m_bonusTargetWidget	= new QLabel;
	layout->addWidget( m_bonusTargetWidget );
	
	m_bonusResultWidget	= new QLabel;
	layout->addWidget( m_bonusResultWidget );
	
	m_bonusWidget->hide();	
}
DJGameDesktop::~DJGameDesktop()
{ 
	djDebug()<<"DJGameDesktop destructor";
	qDeleteAll(m_showViews);
	m_showViews.clear();
	qDeleteAll(m_nameItems);
	m_nameItems.clear();
	delete m_clockItem;
	m_clockItem 	= 0;
	delete m_hostItem;
	m_hostItem 	= 0;
}
void DJGameDesktop::SetSavable(bool b)
{
	c_bSavable = b;
}
QString	DJGameDesktop::playerItemNameSuffix( DJGameUser* user )
{
	return QString();
}
void DJGameDesktop::lookerIn( quint32 userId, bool in )
{
}
void DJGameDesktop::userArrived( quint32 userId, quint8 seatId )
{
	djDebug() << "DJGameDesktop::userArrived"<<userId<<seatId;
	
	relocateAndRepaintAll();
}
void DJGameDesktop::gameInfo( const unsigned char *buf )
{
	ClearAutoDisappearText();
}
void DJGameDesktop::gameWait( quint16 mask, quint8 status ,quint16 timeout)
{
	djDebug() << "DJGameDesktop::gameWait" << mask << status << timeout; 
	
	m_gameWaitStatus = status;
	m_gameWaitMask = mask;
	m_gameWaitTimeout 	= timeout;
	
	setClockTimeout( mask, timeout );

	switch(status)
	{
		case DJGAME_TABLE_STATUS_WAITSTART :
		{
			if(IsWaittingForMe() && !c_Panel->isLookingOn() )
				m_start->show();
			break;
		}
		default :
			m_start->hide();
			break;
	}
}

bool DJGameDesktop::IsWaittingForMe()
{
	quint16 mymask = (1<<(c_Panel->selfSeatId()-1));
	return (m_gameWaitMask & mymask);
}
void DJGameDesktop::gameTrace( const GeneralGameTrace2Head *gameTrace )
{
	PGeneralGameTrace2Head ptrace = (PGeneralGameTrace2Head)gameTrace;
	c_GameTraces.AppendTrace(ptrace);
}

void DJGameDesktop::magicResult( const MagicResult* magicResult )
{
}
void DJGameDesktop::gameOver( const DJGameOver* gameOver )
{
	QString resultOfScore,resultOfWL;
	for( int i = 0; i < gameOver->chSites; i++ ) {
		if( gameOver->site[i].chSite == DJGAME_GAMEOVER_STATUS_SITES ) {
			PDJGameOverStatus poverstatus = (PDJGameOverStatus)&(gameOver->site[i]);
			//poverstatus->shWinSites == 0 && poverstatus->shLoseSites == 0)
			QList<quint8> seats	= mask2Seat( letoh2(poverstatus->shWinSites) );
			foreach( quint8 seat, seats ) {
				DJGameUser *puser	= c_Panel->userAtSeat( seat );
				if ( puser ) {
					resultOfWL	+= puser->userName()
							+ playerItemNameSuffix( puser )
							+ " "
							+ c_Panel->gameController()->baseSectionName(DJGameController::Wins)
						 	+ "<br>";
				}
			}
			seats	= mask2Seat( letoh2(poverstatus->shLoseSites) );
			foreach( quint8 seat, seats ) {
				DJGameUser *puser	= c_Panel->userAtSeat( seat );
				if ( puser ) {
					resultOfWL	+= puser->userName()
							+ playerItemNameSuffix( puser )
							+ " "
							+ c_Panel->gameController()->baseSectionName(DJGameController::Loses)
						 	+ "<br>";
				}
			}
		}else {
			DJGameUser *puser	= c_Panel->userAtSeat(gameOver->site[i].chSite);
			int score = letoh4(gameOver->site[i].score);
			c_Panel->deltaUserData( puser, score );
			
			if( puser ) {
				resultOfScore	+= QString("<tr><td align=center>%1<td align=center>%2")
								.arg( puser->userName() + playerItemNameSuffix( puser ) )
								.arg( score );
			}
		}
	}
	c_Panel->insertText2Browser( resultOfWL );
	c_Panel->insertGameResult2Browser( resultOfScore );
	
	if(c_bSavable)
	{
		QString res = tr("\n\n Do you want save the battle ?");
		if( QMessageBox::Yes == QMessageBox::information(c_Panel,tr("game report"),res,QMessageBox::Yes,QMessageBox::No) )
		{
			c_GameTraces.SaveGameTrace(NULL,0);
		}
	}
}
QString DJGameDesktop::bonusTarget( const DJGameBonus* bonus )
{
	return QString();
}
void DJGameDesktop::bonusFulfilled( const DJGameBonusFulfill* fulfill )
{
}
bool DJGameDesktop::SupportResearch()
{
	return false;
}
void DJGameDesktop::StaticInitDesktop()
{
}
void DJGameDesktop::StaticGameTrace(GeneralGameTrace2Head *gameTrace)
{
}
void DJGameDesktop::RepaintCurrentStatus()
{
}
//return number of the playing users
//a user may be at seat but not playing. e.g. waiting to join in
quint8	DJGameDesktop::numberOfPlayers() const
{
	if ( c_Panel->gameRoom()->options() & DJGAME_ROOMOPTION_ANYPLAYER )
		return numberOfSeatUsers();
	else
		return c_Panel->numberOfSeats();
}
quint8 DJGameDesktop::numberOfSeatUsers() const
{
	quint8 seatUsers = 0;
	for( quint8 seat = 1;seat <= c_Panel->numberOfSeats(); ++seat ) {
		if( 0 != c_Panel->userIdOfSeat(seat) )
			seatUsers++;
	}
	return seatUsers;
}
QList<quint8> DJGameDesktop::seatsOfPlayers() const
{
	QList<quint8>	seatIds;
	bool isAnyPlayerRoom	= (c_Panel->gameRoom()->options() & DJGAME_ROOMOPTION_ANYPLAYER);
	for ( int seatId = 1; seatId <= c_Panel->numberOfSeats(); ++seatId ) {
		if ( isAnyPlayerRoom ) {
			quint32 userId	= c_Panel->userIdOfSeat( seatId );
			if ( 0 != userId )
				seatIds << seatId;
		}else {
			seatIds << seatId;
		}
	}
	return seatIds;
}
void DJGameDesktop::relocateAndRepaintAll()
{
	djDebug()<<"DJGameDesktop::relocateAndRepaintAll";
	locateShowPositions( m_showPoints, m_showAligns, m_showModes );
	djDebug()<<"m_showPoints"<<m_showPoints;
	djDebug()<<"m_showModes"<<m_showModes;
	
	locateNamePositions( m_namePoints, m_nameAligns, m_nameModes );
	djDebug()<<"m_namePoints"<<m_namePoints;
	djDebug()<<"m_nameModes"<<m_nameModes;
	
	locateClockPosition( m_clockPoint, m_clockAlign, m_clockMode );
	djDebug()<<"m_clockPoint"<<m_clockPoint;
	djDebug()<<"m_clockMode"<<m_clockMode;
	
	locateHostPositions( m_hostPoints, m_hostAligns, m_hostModes );
	djDebug()<<"m_hostPoints"<<m_hostPoints;
	djDebug()<<"m_hostModes"<<m_hostModes;
	
	repaintAllPlayers();
	repaintClock();
	repaintHost();
}
void DJGameDesktop::repaintAllPlayers( bool reload )
{ 
	djDebug() << "DJGameDesktop::repaintAllPlayer" << reload;
	
	for( quint8 seat = 0; seat <= c_Panel->numberOfSeats(); ++seat ) {
		repaintPlayer( seat, reload ); 
	}
}
void DJGameDesktop::repaintPlayer( quint8 seat, bool reload )
{
	repaintShowView( seat, reload );
	repaintNameItem( seat, reload );
}
void DJGameDesktop::repaintShowView( quint8 seat, bool reload )
{ 
  	DJShowView	*showView	= m_showViews.value( seat, 0 );
  	if ( 0 == showView )
  		return;
  	if ( reload ) {
  		DJGameUser	*user	= c_Panel->userAtSeat( seat );
  		if ( user ) {
  			showView->setUser( user );
  		}
  	}
	int mode	= m_showModes.value( seat, DJ_MATRIX_CANVAS_ITEM_HIDE ); 
	if ( DJ_MATRIX_CANVAS_ITEM_HIDE == mode ) {
		showView->hide();
	}else {
		Qt::Alignment	align	= m_showAligns.value( seat, 0 );
		showView->setAlignment( align );
		QPoint	point	= m_showPoints.value( seat, QPoint() );
		if (  DJ_MATRIX_CANVAS_ITEM_MATRIMOVE == mode  )
			showView->matrimove( point );
		else
			showView->move( point );
		showView->show();
	}
}
void DJGameDesktop::repaintNameItem( quint8 seat, bool reload )
{
	DJMatrixCanvasText	*nameItem	= m_nameItems.value( seat, 0 );
	if ( 0 == nameItem )
		return;
	if ( reload ) {
		DJGameUser	*user	= c_Panel->userAtSeat( seat );
  		if ( user ) {
  			nameItem->setText( user->userName() );
  		}
	}
	int mode	= m_nameModes.value( seat, DJ_MATRIX_CANVAS_ITEM_HIDE ); 
	if ( DJ_MATRIX_CANVAS_ITEM_HIDE == mode ) {
		nameItem->hide();
	}else {
		Qt::Alignment	align	= m_nameAligns.value( seat, 0 );
		nameItem->setTextFlags( align );
		QPoint	point	= m_namePoints.value( seat, QPoint() );
		if (  DJ_MATRIX_CANVAS_ITEM_MATRIMOVE == mode  )
			nameItem->matrimove( point.x(), point.y() );
		else
			nameItem->move( point.x(), point.y() );
		nameItem->show();
	}
}
void DJGameDesktop::repaintClock()
{ 
	if ( DJ_MATRIX_CANVAS_ITEM_HIDE == m_clockMode ) {
		m_clockItem->hide();
	}else {
		m_clockItem->setAlignment( m_clockAlign ); 
		
 		if ( DJ_MATRIX_CANVAS_ITEM_MATRIMOVE == m_clockMode  )
 			m_clockItem->matrimove( m_clockPoint.x(), m_clockPoint.y() );
 		else
 			m_clockItem->move( m_clockPoint.x(), m_clockPoint.y() );

		m_clockItem->show();
	}
}
void DJGameDesktop::setClockTimeout( quint16 mask, int seconds )
{  
	djDebug()<<"DJGameDesktop::setClockTimeout"<<mask<<seconds;
	
 	QList<quint8> seats	= mask2Seat( mask );
 	QList<quint8> views;
 	foreach( quint8 seat, seats ) {
 		views << MapSeat2View( seat );
 	}
	
	m_clockItem->setTimeout( views, seconds );
}
void DJGameDesktop::repaintHost()
{
}
void DJGameDesktop::repaintHostItem( quint8 seat )
{
	djDebug()<<"DJGameDesktop::repaintHostItem"<<seat<<m_hostEnabled;
	
	if ( seat < 1 || seat > c_Panel->numberOfSeats() )
		return;
	if ( !m_hostEnabled )
		return;
	int mode	= m_hostModes.value( seat, DJ_MATRIX_CANVAS_ITEM_HIDE );
	if ( DJ_MATRIX_CANVAS_ITEM_HIDE == mode ) {
		m_hostItem->hide();
	}else {
		Qt::Alignment	align	= m_hostAligns.value( seat, 0 );
		m_hostItem->setAlignment( align );
		QPoint	point	= m_hostPoints.value( seat, QPoint() );
		if (  DJ_MATRIX_CANVAS_ITEM_MATRIMOVE == mode  )
			m_hostItem->matrimove( point.x(), point.y() );
		else
			m_hostItem->move( point.x(), point.y() );
		m_hostItem->show();
	}
}
DJShowView *DJGameDesktop::showView( quint8 seat )
{ 
	return m_showViews.value( seat, 0 );
}
DJMatrixCanvasText* DJGameDesktop::nameItem( quint8 seat )
{
	return m_nameItems.value( seat, 0 );
}
QRect DJGameDesktop::idealRectOfShow( quint8 seat ) const
{
	int mode	= m_showModes.value( seat, DJ_MATRIX_CANVAS_ITEM_HIDE );
	//djDebug()<<"idealRectOfShow"<<seat<<"mode"<<mode;
	if (  DJ_MATRIX_CANVAS_ITEM_MATRIMOVE != mode )
		return QRect(); 
	QPoint	point	= m_showPoints.value( seat, QPoint() );
	Qt::Alignment	align	= m_showAligns.value( seat, 0 );
	DJShowView	*showView	= m_showViews.value( seat, 0 );
	QSize	size;
	if ( showView )
		size	= showView->realSize();
	int w	= size.width();
	int h	= size.height();
	
	if( align & Qt::AlignRight )
		point.rx() -= w;
	else if( align & Qt::AlignHCenter )
		point.rx() -= w >> 1;
	if( align & Qt::AlignBottom )
		point.ry() -= h;
	else if( align & Qt::AlignVCenter )
		point.ry() -= h >> 1;
		
	return QRect( point, size );
}
QRect DJGameDesktop::idealRectOfName( quint8 seat ) const
{
	int mode	= m_nameModes.value( seat, DJ_MATRIX_CANVAS_ITEM_HIDE );
	if (  DJ_MATRIX_CANVAS_ITEM_MATRIMOVE != mode )
		return QRect(); 
	QPoint	point	= m_namePoints.value( seat, QPoint() );
	Qt::Alignment	align	= m_nameAligns.value( seat, 0 );
	DJMatrixCanvasText	*nameItem	= m_nameItems.value( seat, 0 );
	QSize	size;
	if ( nameItem )
		size	= nameItem->realSize();
	int w	= size.width();
	int h	= size.height();
	
	if( align & Qt::AlignRight )
		point.rx() -= w;
	else if( align & Qt::AlignHCenter )
		point.rx() -= w >> 1;
	if( align & Qt::AlignBottom )
		point.ry() -= h;
	else if( align & Qt::AlignVCenter )
		point.ry() -= h >> 1;
		
	return QRect( point, size );
}
/*
//return the rect excluding showview
QRect DJGameDesktop::idealAvailableRect()
{
	QRect	availableRect( 0, 0, c_RealWidth, c_RealHeight );
	for( quint8 seat = 1; seat <= c_Panel->numberOfSeats(); ++seat ) {
		int mode	= m_showModes.at(seat);
		if ( DJ_MATRIX_CANVAS_ITEM_MATRIMOVE == mode ) {
			QRect	showRect	= idealRectOfShow( seat );
			quint8 view	= MapSeat2View( seat );
 			switch( view ) {
 			case 1:
 				availableRect.setBottom( showRect.top() );
 				break;
 			case 2:
 				availableRect.setLeft( showRect.right() );
 				break;
 			case 3:
 				availableRect.setTop( showRect.bottom() );
 				break;
 			case 4: 
 				availableRect.setRight( showRect.left() );
 				break;
 			default:
 				break;
 			}
 		}
 	}
 	return availableRect;
}
*/
void DJGameDesktop::GetDesktopCenterPoint(int *x,int *y,int *selfHeight)
{
	if( 0 != selfHeight )
		*selfHeight = 0;
	if( 0 != x )
		*x = c_RealWidth>>1;
	if( 0 != y )
		*y	= c_RealHeight>>1;
}
void DJGameDesktop::locateShowPositions( QList<QPoint>& points, QList<Qt::Alignment>& aligns, QList<int> &modes )
{
	djDebug() << "DJGameDesktop::locateShowPositions";
	
	points.clear();
	aligns.clear();
	modes.clear();
	
	quint8 players	= numberOfPlayers();
	djDebug()<<"players="<<players;
	QList<quint8> seats	= seatsOfPlayers();
	djDebug()<<"seatsOfPlayers="<<seats;
	
	for ( quint8 seat = 0; seat <= c_Panel->numberOfSeats(); ++seat ) {
		points 	<< QPoint();
		aligns	<< 0;
		modes	<< DJ_MATRIX_CANVAS_ITEM_HIDE ;
	}
	int centerX	= c_RealWidth >> 1;
	int centerY	= c_RealHeight >> 1;
	int leftX	= 0;
	int rightX	= c_RealWidth;
	int topY	= 0;
	int bottomY	= c_RealHeight; 
	
	foreach( quint8 seat, seats ) {
 		quint8 view = MapSeat2View(seat);
 		if ( 3 == players  || 4 == players  ) {
    		switch( view ) {
        	case 1: {
        		//points[seat].setX( leftX );
        		//points[seat].setY( bottomY - 1 );
        		//aligns[seat]	= Qt::AlignBottom;
        		//modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	} 
        	case 2: {
        		points[seat].setX( leftX );
        		points[seat].setY( centerY );
        		aligns[seat]	= Qt::AlignVCenter;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	case 3:  {
        		points[seat].setX( centerX );
        		points[seat].setY( topY );
        		aligns[seat]	= Qt::AlignHCenter;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	case 4:  {
        		points[seat].setX( rightX );
        		points[seat].setY( centerY );
        		aligns[seat]	= Qt::AlignRight | Qt::AlignVCenter;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	default:
        		break;
          	}
        }else if ( 2 == players ) {
    		if ( 1 == view ) {
    			points[seat].setX( rightX );
        		points[seat].setY( bottomY );
        		aligns[seat]	= Qt::AlignRight | Qt::AlignBottom;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        	}else {
        		points[seat].setX( rightX );
        		points[seat].setY( topY );
        		aligns[seat]	= Qt::AlignRight;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        	}
    	}else if ( 1 == players ){
 			//points[seat].setX( leftX );
        	//points[seat].setY( topY );
        	//modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
 		}
 	}
}
void DJGameDesktop::locateNamePositions( QList<QPoint>& points, QList<Qt::Alignment>& aligns, QList<int> &modes )
{
	djDebug() << "DJGameDesktop::locateNamePositions";
	
	points.clear();
	aligns.clear();
	modes.clear();
	
	quint8 players	= numberOfPlayers();
	djDebug()<<"players="<<players;
	QList<quint8> seats	= seatsOfPlayers();
	djDebug()<<"seatsOfPlayers="<<seats;
		
	for ( quint8 seat = 0; seat <= c_Panel->numberOfSeats(); ++seat ) {
		points 	<< QPoint();
		aligns 	<< 0;
		modes	<< DJ_MATRIX_CANVAS_ITEM_HIDE; 
	}
	
	foreach( quint8 seat, seats ) {
     	QRect showRect	= idealRectOfShow( seat );
    	quint8 view = MapSeat2View(seat);
    	if ( 3 == players  || 4 == players  ) {
    		switch( view ) {
        	case 1: {
        		points[seat].setX( GetRealWidth()>>1 );
    			points[seat].setY( GetRealHeight() - 1 );
    			aligns[seat]	= Qt::AlignHCenter | Qt::AlignBottom;
    			modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	} 
        	case 2:  {
        		points[seat].setX( showRect.left() + 1 );
        		points[seat].setY( showRect.bottom() + 1 );
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	case 3:  {
        		points[seat].setX( showRect.left() - 1 );
        		points[seat].setY( showRect.top() + 1 );
        		aligns[seat]	= Qt::AlignRight;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	case 4:  {
        		points[seat].setX( showRect.right() - 1 );
        		points[seat].setY( showRect.bottom() + 1 );
        		aligns[seat]	= Qt::AlignRight;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	default:
        		break;
          	}
    	}else if ( 2 == players ) {
    		if ( 1 == view ) {
        		points[seat].setX( showRect.left() - 1 );
        		points[seat].setY( showRect.bottom() - 1 );
        		aligns[seat]	= Qt::AlignRight | Qt::AlignBottom;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        	}else {
        		points[seat].setX( showRect.left() - 1 );
        		points[seat].setY( showRect.top() + 1 );
        		aligns[seat]	= Qt::AlignRight;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        	}
        	
    	}else if ( 1 == players ) { 
    		//points[seat].setX( showRect.left() );
            //points[seat].setY( showRect.bottom() );
            //modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
		}
    }
}

void DJGameDesktop::locateClockPosition( QPoint& point, Qt::Alignment& align, int &mode )
{
	djDebug() << "DJGameDesktop::locateClockPosition";
	
	int centerX, centerY;
    GetDesktopCenterPoint( &centerX, &centerY, 0 );
	quint8 players	= numberOfPlayers();
	if ( players > 2 ) {		
    	point.setX( centerX );
    	point.setY( centerY );
    	align	= Qt::AlignCenter;
    	mode	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
	}else {
		point.setX( GetRealWidth() );
    	point.setY( centerY );
    	align	= Qt::AlignRight | Qt::AlignVCenter;
    	mode	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
	}
}
void DJGameDesktop::locateHostPositions( QList<QPoint>& points, QList<Qt::Alignment>& aligns, QList<int> &modes )
{
	djDebug()<<"DJGameDesktop::locateHostPositions";
	points.clear();
	aligns.clear();
	modes.clear();
	
	quint8 players	= numberOfPlayers();
	djDebug()<<"players="<<players;
	QList<quint8> seats	= seatsOfPlayers();
	djDebug()<<"seatsOfPlayers="<<seats;
		
	for ( quint8 seat = 0; seat <= c_Panel->numberOfSeats(); ++seat ) {
		points 	<< QPoint();
		aligns 	<< 0;
		modes	<< DJ_MATRIX_CANVAS_ITEM_HIDE; 
	}
	
	int space	= 10;
	foreach( quint8 seat, seats ) {
		QRect	showRect	= idealRectOfShow( seat );
    	quint8 view = MapSeat2View(seat);
    	if ( 3 == players  || 4 == players  ) {
        	switch( view ) {
        	case 1: {
        		QRect nameRect	= idealRectOfName( seat );
        		points[seat].setX( nameRect.left() - space );
        		points[seat].setY( GetRealHeight() - 1 );
        		aligns[seat]	= Qt::AlignRight | Qt::AlignBottom;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	} 
        	case 2:  {
        		points[seat].setX( showRect.right() + space );
        		points[seat].setY( showRect.center().y() );
        		aligns[seat]	= Qt::AlignVCenter;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	case 3:  {
        		points[seat].setX( showRect.center().x() );
        		points[seat].setY( showRect.bottom() + space );
        		aligns[seat]	= Qt::AlignHCenter;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	case 4:  {
        		points[seat].setX( showRect.left() - space );
        		points[seat].setY( showRect.center().y() );
        		aligns[seat]	= Qt::AlignRight | Qt::AlignVCenter;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        		break;
        	}
        	default:
        		break;
          	}
    	}else if ( 2 == players ){
    		if ( 1 == view ) {
        		points[seat].setX( GetRealWidth() >> 1 );
        		points[seat].setY( GetRealHeight() - 1 );
        		aligns[seat]	= Qt::AlignHCenter | Qt::AlignBottom;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        	}else {
        		points[seat].setX( GetRealWidth() >> 1 );
        		points[seat].setY( 1 );
        		aligns[seat]	= Qt::AlignHCenter;
        		modes[seat]	= DJ_MATRIX_CANVAS_ITEM_MATRIMOVE;
        	}
    	}
	}
}
void DJGameDesktop::setHostEnabled( bool enabled )
{
	m_hostEnabled	= enabled;
}
void DJGameDesktop::hideHost()
{
	m_hostItem->hide();
}
void DJGameDesktop::MoveItem(Q3CanvasItem* item,QPoint &ps,QPoint &pe)
{
}
QList<quint8> DJGameDesktop::mask2Seat(quint16 mask)
{
	QList<quint8> seatIds;
	quint8 seat	= 1;
	while( 0 != mask ) {
		if( mask & 1 )
			seatIds << seat;
		seat++;
		mask >>= 1;
	}
	return seatIds ;
}
quint8 DJGameDesktop::MapSeat2View(quint8 seat)
{
	if ( 0 == seat )
		return 0;
	
	quint8 players	= numberOfPlayers();
	QList<quint8> seats	= seatsOfPlayers();
	//djDebug()<<"MapSeat2View"<<players<<seats.size();
	int indexOfUserSeat	= seats.indexOf( seat );
	int indexOfSelfSeat	= seats.indexOf( c_Panel->selfSeatId() );
	if ( -1 == indexOfUserSeat || -1 == indexOfSelfSeat )
		return 0;
	
	QList<quint8>	views;
	if ( 1 == players )
		views << 1;
	else if ( 2 == players )
		views << 1 << 3;	
	else if ( 3 == players )
		views << 1 << 2 << 4;
	else if ( 4 == players )
		views << 1 << 2 << 3 << 4;
	
	for ( int i = 0; i < seats.size(); ++i ) {
		int indexOfSeat	= (indexOfSelfSeat + i) % seats.size();
		if ( seat == seats.at(indexOfSeat) ) {
			return views.value(i,0);
		}
	}
	return 0;
}
quint8 DJGameDesktop::MapView2Seat(quint8 view)
{
	for ( quint8 seatId = 1; seatId <= c_Panel->numberOfSeats(); seatId++ ) {
		if ( view == MapSeat2View( seatId ) )
			return seatId;
	}
	return 0;
}
void   DJGameDesktop::SetTotalGames(quint16 sh)
{
	c_TotalGames = sh;
}
quint8 DJGameDesktop::prevSeatId( quint8 seatId, bool isClockwise ) const
{ 
	quint8 prevSeat	= seatId;
	quint8 numberOfSeats	= c_Panel->numberOfSeats();
	do {
		if ( isClockwise  ) {
			prevSeat--;
		}else {
			prevSeat++;
		}
		if ( prevSeat > numberOfSeats ) {
			prevSeat 	-= numberOfSeats;
		}else if ( 0 == prevSeat ) {
			prevSeat 	= numberOfSeats;
		}
	}while( 0 == c_Panel->userIdOfSeat(prevSeat) ); 
	return prevSeat ;
}
quint8 DJGameDesktop::nextSeatId( quint8 seatId, bool isClockwise ) const
{ 
	quint8 nextSeat	= seatId;
	quint8 numberOfSeats	= c_Panel->numberOfSeats();
	do {
		if ( isClockwise  ) {
			nextSeat++;
		}else {
			nextSeat--;
		}
		if ( nextSeat > numberOfSeats ) {
			nextSeat 	-= numberOfSeats;
		}else if ( 0 == nextSeat ) {
			nextSeat 	= numberOfSeats;
		}
	}while( 0 == c_Panel->userIdOfSeat(nextSeat) );
	return nextSeat;
}
DJGameImageItem * DJGameDesktop::FindImageItem(quint16 tid,quint16 sid,quint16 type)
{
	if(tid == 0 || sid == 0 || type == 0)
		return NULL;
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJGameImageItem *item;
    for (; it != list.end(); ++it)
    {
		if(*it && (*it)->rtti() == djgame_imageRTTI)
		{
			item = (DJGameImageItem *)*it;
			
			if( item->tid() == tid && item->sid() == sid && item->type()==type )
			{
				return item;
			}
				
		}
    }
	return NULL;
}
	
DJGameTextItem * DJGameDesktop::FindTextItem(quint16 tid,quint16 sid,quint16 type)
{
	if(tid == 0 || sid == 0 || type == 0)
		return NULL;
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJGameTextItem *item;
    for (; it != list.end(); ++it)
    {
		if(*it && (*it)->rtti() == djgame_textRTTI)
		{
			item = (DJGameTextItem *)*it;
			
			if( item->tid() == tid && item->sid() == sid && item->type()==type )
			{
				return item;
			}
				
		}
    }
	return NULL;
}

DJGameLineItem * DJGameDesktop::FindLineItem(quint16 tid,quint16 sid,quint16 type)
{
	if(tid == 0 || sid == 0 || type == 0)
		return NULL;
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJGameLineItem *item;
    for (; it != list.end(); ++it)
    {
		if(*it && (*it)->rtti() == djgame_lineRTTI)
		{
			item = (DJGameLineItem *)*it;
			
			if( item->tid() == tid && item->sid() == sid && item->type()==type )
			{
				return item;
			}
				
		}
    }
	return NULL;
}

quint16 DJGameDesktop::ClearLine(quint16 tid,quint16 sid,quint16 type)
{
	quint16 i=0;
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJGameLineItem *item;
    for (; it != list.end(); ++it)
    {
		//LandLordImageItem *item =(LandLordImageItem*)*it;
		if(*it && (*it)->rtti() == djgame_lineRTTI)
		{
			item = (DJGameLineItem *)*it;
			
			if( (tid == 0 || item->tid() == tid) &&
					(sid == 0 || item->sid() == sid) &&
					(type == 0 || item->type()==type) )
			{
				delete item;
				if(tid != 0 && sid != 0 && type != 0)
					return 1;
				i++;
			}
				
		}
    }
	return i;
}

quint16 DJGameDesktop::ClearText(quint16 tid,quint16 sid,quint16 type)
{
	quint16 i=0;
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJGameTextItem *item;
    for (; it != list.end(); ++it)
    {
		//LandLordImageItem *item =(LandLordImageItem*)*it;
		if(*it && (*it)->rtti() == djgame_textRTTI)
		{
			item = (DJGameTextItem *)*it;
			
			if( (tid == 0 || item->tid() == tid) &&
					(sid == 0 || item->sid() == sid) &&
					(type == 0 || item->type()==type) )
			{
				delete item;
				if(tid != 0 && sid != 0 && type != 0)
					return 1;
				i++;
			}
				
		}
    }
	return i;
}
void DJGameDesktop::ClearAutoDisappearText()
{
	Q3CanvasItemList list = canvas()->allItems();
    for ( Q3CanvasItemList::Iterator it = list.begin(); it != list.end(); ++it)
    {
    	Q3CanvasItem	*item	= *it;
		if( item && item->rtti() == DJAutoDisappearText::RTTI )
		{
			delete item;
		}
    }
}
void DJGameDesktop::ShowAutoDisappearText( const QString& text, int second ) const
{
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJAutoDisappearText *item;
	int	y	= 0;
    for (; it != list.end(); ++it)
    {
		if(*it && (*it)->rtti() == DJAutoDisappearText::RTTI )
		{
			item = (DJAutoDisappearText *)*it;
			y	= qMax(y,item->boundingRect().bottom());				
		}
    }
    if ( 0 == y )
    	y	= 100;
	DJAutoDisappearText* autoText	= new DJAutoDisappearText(second, text, canvas());
	QFont	font	= autoText->font();
	font.setPointSize( 20 );
	font.setBold( true );
	autoText->setFont( font );
	autoText->setColor( Qt::red );
	autoText->move( width() - autoText->boundingRect().width() >> 1, y);
	autoText->setZ(Z_AUTO_DISAPPEAR_TEXT);
	autoText->show();
}
quint16 DJGameDesktop::ClearImage(quint16 tid,quint16 sid,quint16 type)
{
	quint16 i=0;
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJGameImageItem *item;
    for (; it != list.end(); ++it)
    {
		if(*it && (*it)->rtti() == djgame_imageRTTI)
		{
			item = (DJGameImageItem *)*it;
			
			if( (tid == 0 || item->tid() == tid) &&
					(sid == 0 || item->sid() == sid) &&
					(type == 0 || item->type()==type) )
			{
				delete item;
				if(tid != 0 && sid != 0 && type != 0)
					return 1;
				i++;
			}
				
		}
    }
	return i;
}
void DJGameDesktop::SetTraceManager(DJGameTraceManager &traces)
{
	c_GameTraces = traces;
	int i=1;
	char buffer[260];
	PGeneralGameTrace2Head ptrace=(PGeneralGameTrace2Head)buffer;
	unsigned short shLen,shSteps=c_GameTraces.GetCurrentStepNumber();
	StaticInitDesktop();
	while(i<=shSteps)
	{
		shLen = 260;
		if(!c_GameTraces.Next(buffer,&shLen))
			return;
		StaticGameTrace(ptrace);
		i++;
	}
}

bool DJGameDesktop::isCloseable()
{
	if(m_gameWaitStatus == DJGAME_TABLE_STATUS_WAITSTART && IsWaittingForMe())
		return true;
	return false;
}
void DJGameDesktop::resizeEvent( QResizeEvent * event )
{
	Q3CanvasView::resizeEvent( event );
	//canvas()->resize( event->size().width(), event->size().height() );
	canvas()->resize( visibleWidth(), visibleHeight() );
	c_resizeTimer->start();
}
/*
void DJGameDesktop::MoveStartButton(int x,int y)
{
	m_start->move(x,y);
} 
*/
void DJGameDesktop::HandleResizeTimeout()
{
	djDebug() << "DJGameDesktop::HandleResizeTimeout";
	
	calculateAndSetCurrentMatrix();
	
	handleMatrixChanged( c_matrix );
	
	QPixmap pix( GetGamePanel()->gameController()->gameResDir() + "/image/base/background.png");
	if ( !pix.isNull() ) {
		pix	= pix.scaled( visibleWidth(),visibleHeight(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
		canvas()->setBackgroundPixmap( pix );
	}
}
void DJGameDesktop::handleMatrixChanged( const QMatrix& matrix )
{
	djDebug()<<"DJGameDesktop::handleMatrixChanged"<<matrix;
	
	Q3CanvasItemList list = canvas()->allItems();
    Q3CanvasItemList::Iterator it = list.begin();
	DJGameImageItem *itemimage;
	DJGameTextItem  *itemtext;
	DJGameDesktopSpriteItem *itemsprite;
	DJGameLineItem			*itemline;
    for (; it != list.end(); ++it)
    {
		if(*it)
		{
			if(	(*it)->rtti() == djgame_imageRTTI)
			{
				itemimage = (DJGameImageItem *)*it;
				itemimage->setMatrix(c_matrix);
			}else if(	(*it)->rtti() == djgame_textRTTI)
			{
				itemtext = (DJGameTextItem *)*it;
				itemtext->setMatrix(c_matrix);
			}else if(	(*it)->rtti() == djgame_spriteRTTI)
			{
				itemsprite = (DJGameDesktopSpriteItem *)*it;
				itemsprite->setMatrix(c_matrix);
			}else if(	(*it)->rtti() == djgame_lineRTTI)
			{
				itemline = (DJGameLineItem *)*it;
				itemline->setMatrix(c_matrix);
			}
		}
	}
	foreach( DJShowView *showView, m_showViews ) {
		if ( showView  ) {
			showView->setExternalMatrix( matrix );
		}
	}
	foreach( DJMatrixCanvasText *nameItem, m_nameItems ) {
		if ( nameItem  ) {
			nameItem->setExternalMatrix( matrix );
		}
	}
	
	QMatrix m(0.4,0,0,0.4,0,0);
	m_clockItem->setInnerMatrix( m );
	m_clockItem->setExternalMatrix( matrix );
		
	m_hostItem->setExternalMatrix( matrix );
	
	relocateAndRepaintAll();
	
	int x,y,tx,ty,is;
	GetDesktopCenterPoint(&x,&y,&is);
	matrix.map(x,y,&tx,&ty);
	
	m_start->move( tx - (m_start->width()>>1),
					ty + (clockItem()->realSize().height()>>1) );
	m_bonusWidget->move( visibleWidth() - m_bonusWidget->width(), 2 );
}
void DJGameDesktop::contentsMousePressEvent(QMouseEvent* e)
{	
	QPoint pp;
	
	pp.setX( static_cast<int>((e->pos().x()-c_matrix.dx())/c_matrix.m11()) );
	pp.setY( static_cast<int>((e->pos().y()-c_matrix.dy())/c_matrix.m22()) );
	
	Q3CanvasItemList l=canvas()->collisions(e->pos());
    Q3CanvasItemList::Iterator it=l.begin();
	Q3CanvasItem * item = 0;
    if (it != l.end())
	{
		item = *it;
	}
	handleItemClicked(e->button(),pp, item);
}
void DJGameDesktop::contentsMouseDoubleClickEvent(QMouseEvent* e)
{ 	
	QPoint pp;
	
	pp.setX( static_cast<int>((e->pos().x()-c_matrix.dx())/c_matrix.m11()) );
	pp.setY( static_cast<int>((e->pos().y()-c_matrix.dy())/c_matrix.m22()) );
	
	Q3CanvasItemList l=canvas()->collisions(e->pos());
    Q3CanvasItemList::Iterator it=l.begin();
	Q3CanvasItem * item = 0;
    if (it != l.end())
	{
		item = *it;
	}
	handleItemDoubleClicked(e->button(),pp, item);
}
bool DJGameDesktop::handleItemClicked(Qt::MouseButton btn,const QPoint& pos,Q3CanvasItem *item)
{
	djDebug()<<"DJGameDesktop::handleItemClicked";
	return false;
	/*
	quint8 sid = 0;
	if(item->rtti() == djgame_imageRTTI)
	{
		DJGameImageItem *it = (DJGameImageItem*)item;
		if(it->tid() == DJGAME_DESKTOP_TID_AVATAR && it->type() == DJGAME_DESKTOP_TYPE_PLAYER)
		{
			sid = it->sid();
		}
	}else if(item->rtti() == djgame_textRTTI)
	{
		DJGameTextItem *it = (DJGameTextItem*)item;
		if(it->tid() == DJGAME_DESKTOP_TID_USERNAME && it->type() == DJGAME_DESKTOP_TYPE_PLAYER)
		{
			sid = it->sid();
		}
	}
	if(sid != 0)
	{
		DJGameUser *puser;
		quint32 uid;
		uid = c_Panel->userIdOfSeat(sid);
		if ( Qt::LeftButton == btn )
			c_Panel->insertPlayerName2Editor( uid );
		else if ( Qt::RightButton == btn )
			c_Panel->showPlayerContextMenu( uid );
		return true;
	}
	*/
	return false;
}
bool DJGameDesktop::handleItemDoubleClicked(Qt::MouseButton btn,const QPoint& pos,Q3CanvasItem *item)
{
	djDebug()<<"DJGameDesktop::handleItemDoubleClicked";
	return false;
}
void DJGameDesktop::ClickStart()
{
	djDebug()<<"DJGameDesktop::ClickStart";
	m_start->hide();
	
	QByteArray buf	= c_Panel->makeGameData( DJGAME_PROTOCOL_SUBTYPE_START );
	
	DJClientRequest request( buf );
	c_Panel->sendRequest( request );
	
	c_TotalGames ++;
	emit gameStarted();
}
/*
void DJGameDesktop::gameStart()
{
	djDebug()<<"DJGameDesktop::gameStart";
	m_start->hide();
	c_TotalGames ++;
	emit gameStarted();
}
*/
void DJGameDesktop::calculateAndSetCurrentMatrix()
{
	int	w	= visibleWidth();
	int	h	= visibleHeight();
	
	qreal a = 1.0;
	qreal b = 1.0;
	qreal c = 1.0;
	if(c_RealWidth != 0 && c_RealHeight != 0)
	{
		a = static_cast<qreal>(w)/static_cast<qreal>(c_RealWidth);
		b = static_cast<qreal>(h)/static_cast<qreal>(c_RealHeight);
		c = qMin(a,b);
	}
	
	qreal dx = (static_cast<qreal>(w) - (c_RealWidth*c)) / 2.0;
	qreal dy = (static_cast<qreal>(h) - (c_RealHeight*c)) / 2.0;
	
	c_matrix.setMatrix(c,0,0,c,dx,dy);
}
void DJGameDesktop::setRealSize( quint32 width, quint32 height )
{
	//if ( c_RealWidth != width || c_RealHeight != height ) {
		c_RealWidth	= width;
		c_RealHeight	= height;

		calculateAndSetCurrentMatrix();
		handleMatrixChanged( c_matrix );
	//}
}
quint16	DJGameDesktop::GetTextItemHeight(DJGameTextItem *t)
{
	c_forTestStringWidthHeight->setText(t->text());
	c_forTestStringWidthHeight->setFont(t->font());
	
	QRect rt= c_forTestStringWidthHeight->boundingRect();
	return rt.height();
}
quint16	DJGameDesktop::GetTextItemWidth(DJGameTextItem *t)
{
	c_forTestStringWidthHeight->setText(t->text());
	c_forTestStringWidthHeight->setFont(t->font());
	
	QRect rt= c_forTestStringWidthHeight->boundingRect();
	return rt.width();
}

void DJGameDesktop::SendGameTrace(quint8 trace,char *data,quint8 chLen,AclProc aclProc,const QVariant& parameters )
{
	unsigned char buffer[255];
	PGeneralGameTrace2Head ptrace = (PGeneralGameTrace2Head)buffer;
	if(buffer == NULL)
		chLen = 0;
	ptrace->chTable = c_Panel->tableId();
	ptrace->chSite = c_Panel->selfSeatId();
	ptrace->chType = trace;
	ptrace->chBufLen = chLen;
	if(chLen > 0)
		memcpy(ptrace->chBuf,data,chLen);
	QByteArray buf	= c_Panel->makeGameData( DJGAME_PROTOCOL_SUBTYPE_GAMETRACE2,QByteArray((char *)buffer,sizeof(GeneralGameTrace2Head)+ptrace->chBufLen) );

	DJClientRequest request( buf ,aclProc,parameters);
	c_Panel->sendRequest( request );
}
void DJGameDesktop::changeBackgroundColor( const QColor& color )
{
	canvas()->setBackgroundColor( color );
	QPalette pal = palette();
	pal.setBrush(QPalette::Background,color);
	setPalette(pal);
	SetSettingGameDesktopColor ( c_Panel->gameController()->gameName(), color );
}
/////////////////////////////////////////////////
DJGameChessTimerItem::DJGameChessTimerItem(Q3Canvas * cv,DJGameDesktop *desktop,PDJGameChessTimer pchesstimer)
	:QObject(desktop)
{
	c_Canvas = cv;
	c_Desktop = desktop;
	if(pchesstimer != NULL)
	{
		memcpy(&c_chessTimer,pchesstimer,sizeof(DJGameChessTimer));
		c_chessTimer.shBaseTime = letoh2(pchesstimer->shBaseTime);
	}else
		memset(&c_chessTimer,0,sizeof(DJGameChessTimer));
	QString str;
	QMatrix m = desktop->GetCurrentMatrix();
	str=tr("Basic Time");
	
	c_basictimetext = new DJGameTextItem(str,c_Canvas,m,DJGAME_DESKTOP_TID_RULE_BASETEXT,3,DJGAME_DESKTOP_TYPE_RULE);
	c_basictimetext->setColor(QColor(0,0,0xFF));
	
	c_basictime = new DJGameTextItem(str,c_Canvas,m,DJGAME_DESKTOP_TID_RULE_BASETIME,3,DJGAME_DESKTOP_TYPE_RULE);
	c_basictime->setColor(QColor(0xFF,0,0));
	
	str = tr("Fast");
	c_dumiaotext = new DJGameTextItem(str,c_Canvas,m,DJGAME_DESKTOP_TID_RULE_FASTTEXT,3,DJGAME_DESKTOP_TYPE_RULE);
	c_dumiaotext->setColor(QColor(0,0,0xFF));
	
	str=QString("0");
	c_dumiaotime = new DJGameTextItem(str,c_Canvas,m,DJGAME_DESKTOP_TID_RULE_FASTTIME,3,DJGAME_DESKTOP_TYPE_RULE);
	c_dumiaotime->setColor(QColor(0xFF,0,0));
	
	str = tr("Reserve");
	c_timestext = new DJGameTextItem(str,c_Canvas,m,DJGAME_DESKTOP_TID_RULE_TIMEOUTTEXT,3,DJGAME_DESKTOP_TYPE_RULE);
	c_timestext->setColor(QColor(0,0,0xFF));
	
	str=QString("0");
	c_times = new DJGameTextItem(str,c_Canvas,m,DJGAME_DESKTOP_TID_RULE_TIMEOUTTIME,3,DJGAME_DESKTOP_TYPE_RULE);;
	c_times->setColor(QColor(0xFF,0,0));
	
	ModifyTimeText();
	
	c_basictimetext->setHAlignment(Qt::AlignHCenter);
	c_basictime->setHAlignment(Qt::AlignHCenter);
	c_dumiaotext->setHAlignment(Qt::AlignHCenter);
	c_dumiaotime->setHAlignment(Qt::AlignHCenter);
	c_timestext->setHAlignment(Qt::AlignHCenter);
	c_times->setHAlignment(Qt::AlignHCenter);
		
	c_timer = new QTimer(this);
    connect(c_timer,SIGNAL(timeout()),this,SLOT(HandleTimeout()));
	
}

void DJGameChessTimerItem::ModifyTimeText()
{
	char buffer[100];
	
	sprintf(buffer,"%d:%d:%d",c_chessTimer.shBaseTime/3600,
				(c_chessTimer.shBaseTime%3600)/60,(c_chessTimer.shBaseTime%3600)%60);
	c_basictime->setText(QString(buffer));
	
	sprintf(buffer,"%d:%d",c_chessTimer.chTimeAfterBaseTime/60,
				c_chessTimer.chTimeAfterBaseTime%60);
	c_dumiaotime->setText(QString(buffer));
	
	sprintf(buffer,"%d-%d:%d",c_chessTimer.chTimes,
				c_chessTimer.chTimeAfterTimeout/60,c_chessTimer.chTimeAfterTimeout%60);
	QString str=QString(buffer)+tr("times");
	c_times->setText(QString(buffer));
	
}
void DJGameChessTimerItem::setTimer(PDJGameChessTimer pchesstimer)
{
	if(pchesstimer != NULL)
	{
		memcpy(&c_chessTimer,pchesstimer,sizeof(DJGameChessTimer));
		c_chessTimer.shBaseTime = letoh2(pchesstimer->shBaseTime);
	}else
		memset(&c_chessTimer,0,sizeof(DJGameChessTimer));
	ModifyTimeText();
}

void DJGameChessTimerItem::startTimer()
{
	c_iStart = time(NULL);
	c_iElps = 0;
	c_timer->start(1000,false);
}

void DJGameChessTimerItem::pauseTimer()
{
	c_iStart = 0;
	c_iElps = 0;
	c_timer->stop();
}

void DJGameChessTimerItem::HandleTimeout()
{
	//char buffer[100];
	int ispace = time(NULL)-c_iStart;
	if(ispace > c_iElps)
		ispace = ispace-c_iElps;
	else
		return;
	c_iElps += ispace;
	if(c_chessTimer.shBaseTime > ispace)
	{
		c_chessTimer.shBaseTime -= ispace;
	}else
	{
		if(c_chessTimer.shBaseTime != 0)
		{
			ispace -= c_chessTimer.shBaseTime;
			c_chessTimer.shBaseTime = 0;
		}
		if(c_chessTimer.chTimeAfterBaseTime > ispace)
		{
			c_chessTimer.chTimeAfterBaseTime -= ispace;
			if ( c_chessTimer.chTimeAfterBaseTime <= 10 )
				emit Last10Launch(c_chessTimer.chTimeAfterBaseTime);
		}else if(c_chessTimer.chTimes > 0)
		{
			ispace -= c_chessTimer.chTimeAfterBaseTime;
			c_chessTimer.chTimeAfterBaseTime = 0;
			c_chessTimer.chTimes --;
			c_chessTimer.chTimeAfterBaseTime += (c_chessTimer.chTimeAfterTimeout-ispace);
		}
	}
	ModifyTimeText();
	c_timer->start(1000,false);
}

void DJGameChessTimerItem::show()
{
	c_basictimetext->show();
	c_basictime->show();
	c_dumiaotext->show();
	c_dumiaotime->show();
	c_timestext->show();
	c_times->show();
}

void DJGameChessTimerItem::hide()
{
	c_basictimetext->hide();
	c_basictime->hide();
	c_dumiaotext->hide();
	c_dumiaotime->hide();
	c_timestext->hide();
	c_times->hide();
}

quint16 DJGameChessTimerItem::move(QRect & rt,bool b2Down)
{
//	c_BoundingRect = rt;;
	QFont f = c_basictime->font();

	f.setPointSize(12);
	c_basictimetext->setFont(f);
	c_basictime->setFont(f);
	c_dumiaotext->setFont(f);
	c_dumiaotime->setFont(f);
	c_timestext->setFont(f);
	c_times->setFont(f);
	
	quint16 h = c_Desktop->GetTextItemHeight(c_basictime);
	qint32 y;
	if(b2Down)
	{
/*		c_basictimetext->setVAlignment(Qt::AlignTop);
		c_basictime->setVAlignment(Qt::AlignTop);
		c_dumiaotext->setVAlignment(Qt::AlignTop);
		c_dumiaotime->setVAlignment(Qt::AlignTop);
		c_timestext->setVAlignment(Qt::AlignTop);
		c_times->setVAlignment(Qt::AlignTop);
*/		y = rt.top();
	}else
	{
/*		c_basictimetext->setVAlignment(Qt::AlignBottom);
		c_basictime->setVAlignment(Qt::AlignBottom);
		c_dumiaotext->setVAlignment(Qt::AlignBottom);
		c_dumiaotime->setVAlignment(Qt::AlignBottom);
		c_timestext->setVAlignment(Qt::AlignBottom);
		c_times->setVAlignment(Qt::AlignBottom);
*/		y = rt.bottom()-h*6;
	}
	
	quint32 x = rt.left()+(rt.width()>>1);
	
	c_basictimetext->move(x,y);
	y += (h-3);
	c_basictime->move( x,y);
	y += (h+3);
	
	c_dumiaotext->move(x,y);
	y += (h-3);
	c_dumiaotime->move(x,y);
	y += (h+3);
	
	c_timestext->move(x,y);
	y += (h-3);
	c_times->move(x,y);
	
	return h*6;
}
DJGameChessTimerItem::~DJGameChessTimerItem()
{
}
////////////////////////////////////////////////////////////////////

