#include <screenw.h>
#include "dlgbankrange.h"
#include <QDebug>
#include <QFile>
#include <labelbtn.h>
#include <QPixmap>
#include <supportfuncs.h>
#include <fstream>

#include <string.h>

using namespace std;

extern int PletterMain( int dataSize, unsigned char *pData, string destfilename );


const int CScreenW::PAL_ALL = 100;

CScreenW::CScreenW()
{
	setupUi( this );	
}


void CScreenW::Initialize()
{
	int i;
	int x, y;
	QPalette pal;
	QWidget *pTab;
	QImage image;

		
	m_pLblScreen = new CLabelBtn( m_pFrmScreen, 32*16, 24*16 );
	m_pLblScreen->setGeometry( 3, 3, 32*16, 24*16 );
	m_pLblScreen->setMouseTracking( true );
	m_pLblScreen->show();

	m_pLblSelection = new CLabelBtn( m_pFrmScreen, 0, 0 );
	m_pLblSelection->setGeometry( 0, 0, 0, 0 );
	m_pLblSelection->setFrameShape( QFrame::Box );
	m_pLblSelection->setFrameShadow( QFrame::Raised );
	pal = m_pLblSelection->palette();
	pal.setColor( QPalette::Dark, Qt::green );
	m_pLblSelection->setPalette( pal );



	connect( m_pLblScreen, SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnScreenClickLeft( int, int ) ) );
	connect( m_pLblScreen, SIGNAL( onReleasedLeft( int, int ) ), this, SLOT( OnScreenReleaseLeft( int, int ) ) );
	connect( m_pLblScreen, SIGNAL( onReleasedRight( int, int ) ), this, SLOT( OnScreenReleaseRight( int, int ) ) );
	connect( m_pLblScreen, SIGNAL( onMouseMoveEvent( int, int ) ), this, SLOT( OnScreenMouseMoveEvent( int, int ) ) );

	
	m_pTabBank = new QTabWidget( this );
	m_pTabBank->setGeometry( QRect( 5, 420, 596, 184 ) );

	for( i = 0; i < 3; i++ )
	{
		pTab = new QWidget();
		m_pTabBank->addTab( pTab, QString());

		m_pTabBank->setTabText( m_pTabBank->indexOf( pTab), QString( "Bank %1" ).arg( i ) );
		
		m_pFrmBank[i] = new QFrame( pTab );
		m_pFrmBank[i]->setGeometry( QRect( 5, 10, 591, 194) );
		m_pFrmBank[i]->setFrameShape( QFrame::StyledPanel );
		m_pFrmBank[i]->setFrameShadow( QFrame::Raised );

		m_pLblBank[i] = new CLabelBtn( m_pFrmBank[i], 32*18, 8*18 );
		m_pLblBank[i]->setGeometry( 0, 0, m_pFrmBank[i]->width(), m_pFrmBank[i]->height() );
		
		m_pLblBank[i]->show();
	}
	
	connect( m_pTabBank, SIGNAL( currentChanged( int ) ), this, SLOT( OnBankChanged( int ) ) );
	connect( m_pLblBank[0], SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnBank0Click( int, int ) ) );
	connect( m_pLblBank[1], SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnBank1Click( int, int ) ) );
	connect( m_pLblBank[2], SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnBank2Click( int, int ) ) );

	m_pLblBank[0]->setMouseTracking( true );
	m_pLblBank[1]->setMouseTracking( true );
	m_pLblBank[2]->setMouseTracking( true );
                /*
	connect( m_pLblBank[0], SIGNAL( onReleasedLeft( int, int ) ), this, SLOT( OnBankReleaseLeft( int, int ) ) );
	connect( m_pLblBank[1], SIGNAL( onReleasedLeft( int, int ) ), this, SLOT( OnBankReleaseLeft( int, int ) ) );
	connect( m_pLblBank[2], SIGNAL( onReleasedLeft( int, int ) ), this, SLOT( OnBankReleaseLeft( int, int ) ) );
*/
	connect( m_pLblBank[0], SIGNAL( onDoubleClickedLeft( int, int ) ), this, SLOT( OnBank0DoubleClick( int, int ) ) );
	connect( m_pLblBank[1], SIGNAL( onDoubleClickedLeft( int, int ) ), this, SLOT( OnBank1DoubleClick( int, int ) ) );
	connect( m_pLblBank[2], SIGNAL( onDoubleClickedLeft( int, int ) ), this, SLOT( OnBank2DoubleClick( int, int ) ) );
	
	connect( m_pGrOneBank,   SIGNAL( clicked() ), this, SLOT( OnOneBank() ) );
		
	m_pLblPalette = new CLabelBtn( m_pFrmPalette, 40, 96 );
	m_pLblPalette->setGeometry( 0, 0, m_pFrmPalette->width(), m_pFrmPalette->height() );

	connect( m_pLblPalette, SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnPaletteClick( int, int ) ) );

	m_pLblPalBack = new CLabelBtn( m_pFrmDesigner, 16, 10 );
	m_pLblPalBack->setGeometry( m_pLblPalBackC->x(), m_pLblPalBackC->y() + 25, 16, 10 );
	
	m_pLblPalFore = new CLabelBtn( m_pFrmDesigner, 16, 10 );
	m_pLblPalFore->setGeometry( m_pLblPalForeC->x(), m_pLblPalForeC->y() + 25, 16, 10 );

	connect( m_pLblPalBack, SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnPalBackClick( int, int ) ) );
	connect( m_pLblPalFore, SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnPalForeClick( int, int ) ) );
	
	m_pLblTile = new CLabelBtn( m_pFrmTile, 96, 96 );
	m_pLblTile->setGeometry( 2, 2, m_pFrmTile->width(), m_pFrmTile->height() );
	
	connect( m_pLblTile, SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnTileClickLeft( int, int ) ) );
	connect( m_pLblTile, SIGNAL( onClickedRight( int, int ) ), this, SLOT( OnTileClickRight( int, int ) ) );
	
	m_pLblColors = new CLabelBtn( m_pFrmColors, 96, 12 );
	m_pLblColors->setGeometry( 3, 3, 12*16, 16 );
	
	image = QImage( m_pLblColors->width(), m_pLblColors->height(), QImage::Format_RGB32 );
	
	for( x = 0; x < 16; x++ ) CSupportFuncs::SetPixelRect( &image, x*12, 0, CSupportFuncs::COLORS_TABLE[x], 12, 16 );
	
	m_pLblColors->put_Image( image );
	
	connect( m_pLblColors, SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnColorsClick( int, int ) ) );

	connect( m_pBtnFromBank, SIGNAL( clicked() ), this, SLOT( OnFromBank() ) );
	connect( m_pBtnToBank, SIGNAL( clicked() ), this, SLOT( OnToBank() ) );

	connect( m_pRadBack, SIGNAL( clicked() ), this, SLOT( OnRadBack() ) );
	connect( m_pRadFore, SIGNAL( clicked() ), this, SLOT( OnRadFore() ) );
	
	m_SelColor = QPoint( 1, 0 );
	
	for( x = 0; x < 256*3; x++ ) m_Screen[x] = 0;
	for( y = 0; y < 3; y++ ) for( x = 0; x < 256; x++ )	m_TilesBank[x][y] = CTile();
	
	m_pRadFore->setChecked( true );
	
	connect( m_pGrTileClear, SIGNAL( clicked() ), this, SLOT( OnTileClear() ) );
	connect( m_pGrTileReorder, SIGNAL( clicked() ), this, SLOT( OnTileReorder() ) );
	connect( m_pGrTileShiftDown, SIGNAL( clicked() ), this, SLOT( OnTileShiftDown() ) );
	connect( m_pGrTileShiftUp, SIGNAL( clicked() ), this, SLOT( OnTileShiftUp() ) );		
	connect( m_pGrTileShiftLeft, SIGNAL( clicked() ), this, SLOT( OnTileShiftLeft() ) );
	connect( m_pGrTileShiftRight, SIGNAL( clicked() ), this, SLOT( OnTileShiftRight() ) );
	connect( m_pGrTileFlipHorizontal, SIGNAL( clicked() ), this, SLOT( OnTileFlipHorizontal() ) );
	connect( m_pGrTileFlipVertical, SIGNAL( clicked() ), this, SLOT( OnTileFlipVertical() ) );
	connect( m_pGrTileInvertColors, SIGNAL( clicked() ), this, SLOT( OnTileInvertColors() ) );
	connect( m_pGrTileRotate, SIGNAL( clicked() ), this, SLOT( OnTileRotate() ) );
	
	setMouseTracking( true );

	for( x = 0; x < 32; x++ )
	{
		m_pColsLabels[x] = new QLabel( QString( "%1" ).arg( x ), this );
		m_pColsLabels[x]->setGeometry( 16*x+26, 5, 16, 16 );
		m_pColsLabels[x]->setAlignment( Qt::AlignCenter );
	    m_pColsLabels[x]->setFrameShape(QFrame::Box);
	    m_pColsLabels[x]->setFrameShadow(QFrame::Raised);
	}

	for( x = 0; x < 24; x++ )
	{
		m_pRowsLabels[x] = new QLabel( QString( "%1" ).arg( x%8 ), this );
		m_pRowsLabels[x]->setGeometry( 6, 16*x+26, 16, 16 );	
		m_pRowsLabels[x]->setAlignment( Qt::AlignCenter );
	    m_pRowsLabels[x]->setFrameShape(QFrame::Box);
	    m_pRowsLabels[x]->setFrameShadow(QFrame::Raised);
	}
	
	m_LastGridValue = QPoint( 0, 0 );

	//
	m_CursorImage = QImage( 16, 16, QImage::Format_RGB32 ); //TODO - 1 No membre
        CSupportFuncs::SetPixelRect( &m_CursorImage, 0, 0, CSupportFuncs::COLORS_TABLE[15], 16, 16 );
	m_pLblCursor[0] = new CLabelBtn( m_pFrmScreen, 15, 1 );
	m_pLblCursor[0]->setGeometry( 0, 0, 0, 0 );
	m_pLblCursor[0]->put_Image( m_CursorImage );

	m_pLblCursor[1] = new CLabelBtn( m_pFrmScreen, 1, 15 );
	m_pLblCursor[1]->setGeometry( 0, 0, 0, 0 );
	m_pLblCursor[1]->put_Image( m_CursorImage );

	m_pLblCursor[2] = new CLabelBtn( m_pFrmScreen, 15, 11 );
	m_pLblCursor[2]->setGeometry( 0, 0, 0, 0 );
	m_pLblCursor[2]->put_Image( m_CursorImage );

	m_pLblCursor[3] = new CLabelBtn( m_pFrmScreen, 1, 15 );
	m_pLblCursor[3]->setGeometry( 0, 0, 0, 0 );
	m_pLblCursor[3]->put_Image( m_CursorImage );

	for( i = 0; i < 256; i++ )
	{
                m_pGrBackgroundTiles0->addItem( QString( "%1" ).arg( i ) );
                m_pGrBackgroundTiles1->addItem( QString( "%1" ).arg( i ) );
                m_pGrBackgroundTiles2->addItem( QString( "%1" ).arg( i ) );
	}
/*

	m_pLblBankTile = new CLabelBtn( this, 16, 16 );
	m_pLblBankTile->setGeometry( 0, 0, 16, 16 );
	m_pLblBankTile->setPixmap( QPixmap( 16, 16 ) );
//	m_pLblBankTile->setMouseTracking( true );
	m_pLblBankTile->setVisible( false );
	//m_pLblBankTile->show();
        */
        /*
	connect( m_pLblBankTile, SIGNAL( onMouseMoveEvent( int, int ) ), this, SLOT( OnBankTileMouseMoveEvent( int, int ) ) );
	connect( m_pLblBankTile, SIGNAL( onReleasedLeft( int, int ) ), this, SLOT(   OnBankTileReleaseLeft( int, int ) ) );
        connect( m_pLblBankTile, SIGNAL( onClickedLeft( int, int ) ), this, SLOT( OnBankTileClickLeft( int, int ) ) );
        connect( m_pLblBankTile, SIGNAL( onDoubleClickedLeft( int, int ) ), this, SLOT( OnBankTileDoubleClickLeft( int, int ) ) );
        m_LastBankTilePos = QPoint( -1, -1 );
*/

	//

//	m_DragDrop = false;

	m_Selecting = false;

	m_SelectionRect = QRect( 0, 0, 0, 0 );
	m_LastClickPos = QPoint( -1, -1 );
	
	m_LastTilesBlockW = m_pGrTilesBlockW->text().toLongLong();
	m_LastTilesBlockH = m_pGrTilesBlockH->text().toLongLong();

        m_pFrmBackgroundTiles->setVisible( false );

	m_Close = false;
}

void CScreenW::UpdateBank( int tile, int bank, bool updateScreen )
{
	PaintTile( &m_BankImages[bank], m_TilesBank[tile][bank], (tile%32)*18+1, (tile/32)*18+1, 2 );

	m_pLblBank[bank]->put_Image( m_BankImages[bank] ); 
	
	if( updateScreen ) UpdateScreen();
}

void CScreenW::InitBanks()
{
	int i, j;
	
	
	for( j = 0; j < 3; j++ ) 
	{
		m_BankImages[j] = m_pLblBank[j]->pixmap()->toImage();

		PaintGrid( &m_BankImages[j], 16, 16 );

		for( i = 0; i < 256; i++ ) 
		{
			PaintTile( &m_BankImages[j], m_TilesBank[i][j], (i%32)*18+1, (i/32)*18+1, 2 );
		}

		m_pLblBank[j]->put_Image( m_BankImages[j] );
	}

	UpdateScreen();
	
	OnBank0Click( 1, 1 );
}

void CScreenW::UpdateScreen()
{
	int i;
	int row, col;
	QImage image;
	
	
	image = QImage( 32*16, 24*16, QImage::Format_RGB32 );
	
	for( i = 0; i < 3; i++ )
	{
		for( row = 0; row < 8; row++ )
		{
			for( col = 0; col < 32; col++ )
			{
				PaintTile( &image, m_TilesBank[ m_Screen[(i*8+row)*32+col] ][ i ], col*16, (i*8+row)*16, 2 );
			}
		}
	}
	m_pLblScreen->put_Image( image );
}


void CScreenW::CopyTile()
{
	if( m_ScreenSelection.size() ) m_ScreenSelectionCopy = m_ScreenSelection;
	else 
	{
		m_CopyTile = m_TilesBank[m_SelTile.x()][m_SelTile.y()];
		m_ScreenSelectionCopy.clear();
	}
}

void CScreenW::PasteTile()
{
	int xI;
	int x, y;
	int i, j;
	QList<int> s;


        if( m_ScreenSelectionCopy.size() )
	{
		xI = m_MouseX / 16;
		y = m_MouseY / 16;
	
		if( m_ScreenSelectionCopy.size() == m_SelectionRect.height() && m_ScreenSelectionCopy.at( 0 ).size() == m_SelectionRect.width()	)
		{
			for( i = 0; i < m_ScreenSelectionCopy.size(); i++ )
			{
				s =  m_ScreenSelectionCopy.at( i );

				if( ( i + y ) > 23 ) break;

				for( j = 0, x = xI; j < s.size(); j++ )
				{
					if( ( j + x ) > 31 ) break;

					m_Screen[(i+y)*32+j+x] = s.at( j );
				}
			}
		}
		else
		{
			for( y = m_SelectionRect.top(), j = 0; y <= m_SelectionRect.bottom(); y++, j++ )
			{
				if( j == m_ScreenSelectionCopy.size() ) j = 0;

				s = m_ScreenSelectionCopy.at( j );

				for( x = m_SelectionRect.left(), i = 0; x <= m_SelectionRect.right(); x++, i++ )
				{
					if( i == m_ScreenSelectionCopy.at( j ).size() ) i = 0;

					m_Screen[y*32+x] = s.at( i );
				}
			}
		}
		UpdateScreen();
	}
	else
	{
		if( m_ScreenSelection.size() )
		{
			for( y = m_SelectionRect.top(); y <= m_SelectionRect.bottom(); y++ )
			{
				for( x = m_SelectionRect.left(); x <= m_SelectionRect.right(); x++ )
				{
					m_Screen[y*32+x] = m_SelTile.x();
				}
			}
			UpdateScreen();
		}
		else
		{
			m_TilesBank[m_SelTile.x()][m_SelTile.y()] = m_CopyTile;
			UpdateBank( m_SelTile.x(), m_SelTile.y() );
		}
	}
}

void CScreenW::PasteTileColors()
{
	int y;
	
	
	for( y = 0; y < 8; y++ )
	{
		m_TilesBank[m_SelTile.x()][m_SelTile.y()].SetForeColor( y, m_CopyTile.GetForeColor( y ) );
		m_TilesBank[m_SelTile.x()][m_SelTile.y()].SetBackColor( y, m_CopyTile.GetBgColor( y ) );
	}
	UpdateBank( m_SelTile.x(), m_SelTile.y() );
}

void CScreenW::OnBank0DoubleClick( int x, int y )
{
	OnBankDoubleClick( x, y, 0 );
}

void CScreenW::OnBank1DoubleClick( int x, int y )
{
	OnBankDoubleClick( x, y, 1 );
}

void CScreenW::OnBank2DoubleClick( int x, int y )
{
	OnBankDoubleClick( x, y, 2 );
}

void CScreenW::OnBankDoubleClick( int /*x*/, int /*y*/, int /*bank*/ )
{
	m_pLblSelection->setGeometry( 0, 0, 0, 0 ); //TODO - 1 Class CSelection
	m_ScreenSelection.clear();

	OnFromBank();
}


void CScreenW::OnBankTileDoubleClickLeft( int x, int y )
{
	OnFromBank();
}
/*
void CScreenW::OnBankTileClickLeft( int x, int y )
{

	int mX, mY;


//	mX = m_pLblBankTile->x() - m_pTabBank->x() - m_pFrmBank[0]->x() - 4;
//	mY = m_pLblBankTile->y() - m_pTabBank->y() - m_pFrmBank[0]->y() - 25;

	qDebug()<<"CScreenW::OnBankTileClickedLEft currentTab="<<m_pTabBank->currentIndex();

	OnBankClick( mX, mY, m_pTabBank->currentIndex() );
}
*/
void CScreenW::OnBank0Click( int x, int y )
{
	OnBankClick( x, y, 0 );
}

void CScreenW::OnBank1Click( int x, int y )
{
	OnBankClick( x, y, 1 );
}

void CScreenW::OnBank2Click( int x, int y )
{
	OnBankClick( x, y, 2 );
}

void CScreenW::OnBankClick( int x, int y, int bank )
{
    m_pLblSelection->setGeometry( 0, 0, 0, 0 );
    m_ScreenSelection.clear();

    CSupportFuncs::SetBorderImage( &m_BankImages[m_SelTile.y()], (m_SelTile.x()%32)*18 + 1, (m_SelTile.x()/32)*18 + 1, 18*m_LastTilesBlockW-1, 18*m_LastTilesBlockH-1, 0xC0C0C0 );
    m_pLblBank[m_SelTile.y()]->put_Image( m_BankImages[m_SelTile.y()] );

    m_SelTile = QPoint( (y/18)*32+(x/18), bank );
    CSupportFuncs::SetBorderImage( &m_BankImages[bank], (m_SelTile.x()%32)*18 + 1, (m_SelTile.x()/32)*18 + 1, 18*m_pGrTilesBlockW->text().toLongLong()-1, 18*m_pGrTilesBlockH->text().toLongLong()-1, 0xffff00 );

    m_LastTilesBlockW = m_pGrTilesBlockW->text().toLongLong();
    m_LastTilesBlockH = m_pGrTilesBlockH->text().toLongLong();

    m_pLblBank[bank]->put_Image( m_BankImages[bank] );//TODO - 1 Serveix?

    m_pLblShowTile->setText( QString( "%1" ).arg( m_SelTile.x() ) );
}

void CScreenW::OnPaletteClick( int x, int y )
{
	m_SelColor = QPoint( x/(int)20, y/(int)12 );

	if( m_SelColor.x() == 0 ) m_pRadBack->click();
	else m_pRadFore->click();
}

void CScreenW::OnPalBackClick( int, int )
{
	m_SelColor = QPoint( 0, PAL_ALL );
	m_pRadBack->click();
}

void CScreenW::OnPalForeClick( int, int )
{
	m_SelColor = QPoint( 1, PAL_ALL );
	m_pRadFore->click();
}


void CScreenW::OnColorsClick( int x, int /*y*/ )
{
	int c;
	int i;
	
	
	c = x / 12;

	if( m_SelColor.x() == 0 ) 
	{
		if( m_SelColor.y() != PAL_ALL )	m_TileDesign.SetBackColor( m_SelColor.y(), c );
		else for( i = 0; i < 8; i++ ) m_TileDesign.SetBackColor( i, c );
	}
	else 
	{
		if( m_SelColor.y() != PAL_ALL )	m_TileDesign.SetForeColor( m_SelColor.y(), c );
		else for( i = 0; i < 8; i++ ) m_TileDesign.SetForeColor( i, c );
	}
	
	SetTileDesign();	
}

void CScreenW::OnTileClickLeft( int x, int y )
{
	x /= 12;
	y /= 12;
	
	if( m_pRadBack->isChecked() ) 
	{
		m_TileDesign.SetBackPixel( x, y );
		m_SelColor = QPoint( 0, y );
	}
	else 
	{
		m_TileDesign.SetForePixel( x, y );
		m_SelColor = QPoint( 1, y );
	}
	 
	SetTileDesign();
}

void CScreenW::OnTileClickRight( int x, int y )
{
	 x /= 12;
	 y /= 12;
	 
	 if( !m_pRadBack->isChecked() ) m_TileDesign.SetBackPixel( x, y );
	 else m_TileDesign.SetForePixel( x, y );
	 
	 SetTileDesign();
}

void CScreenW::OnFromBank()
{
	CopyToTileDesign( m_SelTile.x(), m_SelTile.y() );
}
//TODO - 1 class CUndo
void CScreenW::Undo()
{
	if( m_Undo.size() == 0 ) return;

	if( m_Undo.at( 0 ) == "TOBANK" )
	{
		if( m_Undo.at( 1 ) == "ALLBANKS" )
		{
			m_TilesBank[ m_Undo.at( 2 ).toLongLong() ] [ 0 ] = m_UndoTile;		
			m_TilesBank[ m_Undo.at( 2 ).toLongLong() ] [ 1 ] = m_UndoTile;
			m_TilesBank[ m_Undo.at( 2 ).toLongLong() ] [ 2 ] = m_UndoTile;
			UpdateBank( m_Undo.at( 2 ).toLongLong(), 0 );
		}
		else if( m_Undo.at( 1 ) == "ONEBANK" )
		{
			m_TilesBank[ m_Undo.at( 2 ).toLongLong() ] [ m_Undo.at( 3 ).toLongLong() ] = m_UndoTile;
			UpdateBank( m_Undo.at( 2 ).toLongLong(), m_Undo.at( 3 ).toLongLong() );
		}
		else Q_ASSERT( false );

		m_Undo.clear();
	}
	else if( m_Undo.at( 0 ) == "SCREENCLICK" )
	{
		m_Screen[ m_Undo.at( 2 ).toLongLong() *32 + m_Undo.at( 1 ).toLongLong() ] = m_Undo.at( 3 ).toLongLong();
		
		UpdateScreen();

		m_Undo.clear();
	}
	else
	{
		Q_ASSERT( false );
	}
}

void CScreenW::OnToBank()
{
	if( m_pGrOneBank->isChecked() )
	{
		m_Undo.clear();
		m_Undo<<"TOBANK"<<"ALLBANKS"<<m_SelTile.x();
		m_UndoTile = m_TilesBank[ m_SelTile.x() ] [0 ];

		m_TilesBank[ m_SelTile.x() ][ 0 ] = m_TileDesign;
		m_TilesBank[ m_SelTile.x() ][ 1 ] = m_TileDesign;
		m_TilesBank[ m_SelTile.x() ][ 2 ] = m_TileDesign;
		UpdateBank( m_SelTile.x(), 0 );
	} 
	else 
	{
		m_Undo.clear();
		m_Undo<<"TOBANK"<<"ONEBANK"<<m_SelTile.x()<<m_SelTile.y();
		m_UndoTile = m_TilesBank[ m_SelTile.x() ] [ m_SelTile.y() ];

		m_TilesBank[ m_SelTile.x() ][ m_SelTile.y() ] = m_TileDesign;	
		UpdateBank( m_SelTile.x(), m_SelTile.y() );
	}
}

void CScreenW::OnScreenReleaseRight( int x, int y )
{
	m_pLblSelection->setGeometry( 0, 0, 0, 0 );
	m_ScreenSelection.clear();

	x = x / 16;
	y = y / 16;

	m_Undo.clear();
	m_Undo<<"SCREENCLICK"<<x<<y<<m_Screen[y*32+x];

        m_Screen[y*32 + x] = GetBackgroundTile( y/8 );
	
	UpdateScreen();
}
//TODO - 1 Deshabilitat. Per mes endavant.
int CScreenW::GetBackgroundTile( int y )
{
    if( m_pGrOneBank->isChecked() ) return m_pGrBackgroundTiles0->currentText().toLongLong();

    switch( y )
    {
        case 0: return m_pGrBackgroundTiles0->currentText().toLongLong();
        case 1: return m_pGrBackgroundTiles1->currentText().toLongLong();
        case 2: return m_pGrBackgroundTiles2->currentText().toLongLong();
        default: Q_ASSERT( false ); return 0;
    }
}

void CScreenW::OnScreenClickLeft( int x, int y )
{
	m_ScreenSelection.clear();

	m_Selecting = true;

	m_pLblCursor[0]->setVisible( false );
	m_pLblCursor[1]->setVisible( false );
	m_pLblCursor[2]->setVisible( false );
	m_pLblCursor[3]->setVisible( false );

	m_LastClickPos = QPoint( x, y );
}

void CScreenW::OnScreenReleaseLeft( int x, int y )
{
	int tmp;
	int i, j;
	int xI, yI;
	int xE, yE;
	QList<int> r;


	m_Selecting = false;
	m_ScreenSelection.clear();
	//TODO - 1 xI<xE yI < yE
	if( m_LastClickPos.x() >= 0 && ( abs( m_LastClickPos.x() - x ) >= 8 || abs( m_LastClickPos.y() - y ) >= 8 ) )
	{
		xI = m_LastClickPos.x() / 16 * 16;
		yI = m_LastClickPos.y() / 16 * 16;
		xE = ( x / 16 * 16 );
		yE = ( y / 16 * 16 );

		if( xI > xE )
		{
			tmp = xE;
			xE = xI;
			xI = tmp;
		}

		if( yI > yE )
		{
			tmp = yE;
			yE = yI;
			yI = tmp;
		}
		m_pLblSelection->setGeometry( xI + 3, yI + 2, abs( xI - xE ), abs( yI - yE ) );
		m_pLblSelection->show();

		xI = xI / 16;
		xE = xE / 16;
		yI = yI /16;
		yE = yE / 16;

		m_SelectionRect = QRect( xI, yI, xE - xI, yE - yI );

		for( i = yI; i < yE; i++ )
		{
			r.clear();

			for( j = xI; j < xE; j++ )
			{
				r<<m_Screen[i*32+j];					

			}
			m_ScreenSelection<<r;
		}

		return;
	}

	m_pLblSelection->setVisible( false );

	x = x / 16;
	y = y / 16;

	if( ( y / 8 ) != m_SelTile.y() && !m_pGrOneBank->isChecked() ) return;
	
	m_Undo.clear();
	m_Undo<<"SCREENCLICK"<<x<<y<<m_Screen[y*32+x];

	for( i = 0; i < m_pGrTilesBlockH->text().toLongLong(); i++ )
	{
		for( j = 0; j < m_pGrTilesBlockW->text().toLongLong(); j++ )
		{
            if( ( m_SelTile.x() + (i*32) + j ) < 256 ) m_Screen[(y+i)*32+x+j] = m_SelTile.x()+(i*32)+j;
                        else Q_ASSERT( false );
                }
	}

	UpdateScreen();
}

void CScreenW::OnBankChanged( int index )
{
	OnBankClick( ( m_SelTile.x() % 32 )*18, ( m_SelTile.x() / 32 )*18, index );
}

void CScreenW::CopyToTileDesign( int index, int bank )
{
	m_TileDesign = m_TilesBank[index][bank];
	SetTileDesign();
}

void CScreenW::SetTileDesign()
{
	int y;
	QImage image;
	
	
	image = QImage( 96, 96, QImage::Format_RGB32 );
	
	PaintTile( &image, m_TileDesign, 0, 0, 12 );

	m_pLblTile->put_Image( image );

	image = QImage( 42, 98, QImage::Format_RGB32 );

	for( y = 0; y < 8; y++ )
	{
		CSupportFuncs::SetPixelRect( &image, 0, y*12, CSupportFuncs::COLORS_TABLE[m_TileDesign.GetBgColor( y )], 20, 12 );
		CSupportFuncs::SetPixelRect( &image, 20, y*12, CSupportFuncs::COLORS_TABLE[m_TileDesign.GetForeColor( y )], 20, 12 );
		
		CSupportFuncs::SetBorderImage( &image, 0, y*12, 20, 12, 0xC0C0C0 );
		CSupportFuncs::SetBorderImage( &image, 20, y*12, 20, 12, 0xC0C0C0 );
	}
	m_pLblPalette->put_Image( image );
		
}

void CScreenW::PaintTile( QImage *pImage, CTile &tile, int posX, int posY, int dotSize )
{
	int x, y;
	
	
	for( y = 0; y < 8; y++ )
	{
		for( x = 0; x < 8; x++ )
		{
			CSupportFuncs::SetPixelRect( pImage, posX + x*dotSize, posY + y*dotSize, CSupportFuncs::COLORS_TABLE[tile.GetPixelColor( x, y )], dotSize, dotSize );
		}
	}
}

void CScreenW::PaintGrid( QImage *pImage, int gridWidth, int gridHeight )
{
	int i, j;
	
	
	for( i = 1; i < pImage->height(); i+= ( gridHeight+ 2 ) )
	{
		for( j = 0; j < pImage->width(); j++ ) 
		{
			pImage->setPixel( j, i-1, 0xC0C0C0 );	
			pImage->setPixel( j, i+gridHeight, 0xC0C0C0 );	
		}
	}
	
	for( i = 1; i < pImage->width(); i+= ( gridWidth + 2 ) )
	{
		for( j = 0; j < pImage->height(); j++ ) 
		{
			pImage->setPixel( i-1, j, 0xC0C0C0 );	
			pImage->setPixel( i+gridWidth, j, 0xC0C0C0 );	
		}
	}
	

}

void CScreenW::OnRadBack()
{
	m_SelColor = QPoint( 0, m_SelColor.y() );
}

void CScreenW::OnRadFore()
{
	m_SelColor = QPoint( 1, m_SelColor.y() );
}

void CScreenW::OnTileClear()
{
	m_TileDesign.Reset();
	SetTileDesign();
}

void CScreenW::OnTileReorder()
{
	m_TileDesign.Reorder();
	SetTileDesign();
}

void CScreenW::OnTileRotate()
{
	m_TileDesign.Rotate();
	SetTileDesign();
}

void CScreenW::OnTileInvertColors()
{
	int i;

	for( i = 0; i < 8; i++ ) m_TileDesign.InvertRow( i );
	SetTileDesign();
}

void CScreenW::OnTileShiftDown()
{
	m_TileDesign.ShiftDown();
	SetTileDesign();
}

void CScreenW::OnTileShiftUp()
{
	m_TileDesign.ShiftUp();
	SetTileDesign();
}

void CScreenW::OnTileShiftLeft()
{
	m_TileDesign.ShiftLeft();
	SetTileDesign();
}

void CScreenW::OnTileShiftRight()
{
	m_TileDesign.ShiftRight();
	SetTileDesign();	
}

void CScreenW::OnTileFlipHorizontal()
{
	m_TileDesign.FlipHorizontal();
	SetTileDesign();	
}

void CScreenW::OnTileFlipVertical()
{
	m_TileDesign.FlipVertical();
	SetTileDesign();
}
/*
void CScreenW::OnBankReleaseLeft( int, int )
{
	m_DragDrop = false;
}
*/
void CScreenW::OnBankTileMouseMoveEvent( int x, int y )
{
    /*
	int difX;
	int difY;
	int modd;


	difX = m_LastBankTilePos.x() - x;
	difY = m_LastBankTilePos.y() - y;

	m_pLblBankTile->setGeometry( m_pLblBankTile->x() - difX, m_pLblBankTile->y() - difY, m_pLblBankTile->width(), m_pLblBankTile->height() );

	m_LastBankTilePos = QPoint( x + difX, y + difY );

	OnScreenMouseMoveEvent( m_pLblBankTile->x() - m_pFrmScreen->x(), m_pLblBankTile->y() - m_pFrmScreen->y() );
*/
}
/*
void CScreenW::OnBank0MouseMoveEvent( int x, int y )
{
	OnBankMouseMoveEvent( x, y, 0 );
}

void CScreenW::OnBank1MouseMoveEvent( int x, int y )
{
	OnBankMouseMoveEvent( x, y, 1 );
}

void CScreenW::OnBank2MouseMoveEvent( int x, int y )
{
	OnBankMouseMoveEvent( x, y, 2 );
}

void CScreenW::OnBankMouseMoveEvent( int x, int y, int bank )
{
	int mX, mY;
	int bX, bY;


	bX = mX = ( x / 18 ) * 18;
	mX += ( m_pTabBank->x() + m_pFrmBank[bank]->x() + 4 ); //4 Bordes

	bY = mY = ( y / 18 ) * 18;
	mY += ( m_pTabBank->y() + m_pFrmBank[bank]->y() + 25 ); //25 Pestanyes

	m_pLblBankTile->setGeometry( mX, mY, 17, 17 );

	m_pLblBankTile->put_Image( m_BankImages[bank].copy( bX, bY, 17, 17 ) );
	m_pLblBankTile->setVisible( true );
}
*/
void CScreenW::OnScreenMouseMoveEvent( int x, int y )
{
    QPalette pal;
    int ox, oy;

	if( x < 0 || y < 0 ) return;

    m_MouseX = x;
    m_MouseY = y;

    x /= 16;
    y /= 16;

    if( x > 31 || y >23 ) return;

    if( m_LastGridValue.x() != x || m_LastGridValue.y() != y )
    {
        pal = m_pColsLabels[m_LastGridValue.x()]->palette();
        pal.setColor( QPalette::Dark, Qt::gray );
        m_pColsLabels[m_LastGridValue.x()]->setPalette( pal );
        pal.setColor( QPalette::Dark, Qt::green );
        m_pColsLabels[x]->setPalette( pal );

		Q_ASSERT( m_pRowsLabels[m_LastGridValue.y()] );
        pal = m_pRowsLabels[m_LastGridValue.y()]->palette();
        pal.setColor( QPalette::Dark, Qt::gray );
        m_pRowsLabels[m_LastGridValue.y()]->setPalette( pal );
        pal.setColor( QPalette::Dark, Qt::green );
		Q_ASSERT( m_pRowsLabels[y] );
        m_pRowsLabels[y]->setPalette( pal );
        m_LastGridValue = QPoint( x, y );

        m_pLblShowTileBank->setText( QString( "%1" ).arg( m_Screen[ y*32+x] ) );
    }

    if( m_Selecting )
    {
        if( m_LastClickPos.x() > m_MouseX) ox = m_MouseX;
        else ox = m_LastClickPos.x();

        if( m_LastClickPos.y() > m_MouseY ) oy = m_MouseY;
        else oy = m_LastClickPos.y();

        m_pLblSelection->setGeometry( ox, oy, abs( m_MouseX - m_LastClickPos.x() ), abs( m_MouseY - m_LastClickPos.y() ) );
        m_pLblSelection->setVisible( true );
    }
    else
    {
        m_pLblCursor[0]->setGeometry( x*16+1 + 3,  y*16+1, 14, 1 );
        m_pLblCursor[1]->setGeometry( x*16+20, y*16+1 + 2,  1, 16 );
        m_pLblCursor[2]->setGeometry( x*16+1 + 3,  y*16+21, 14, 1 );
        m_pLblCursor[3]->setGeometry( x*16+1,  y*16+1 + 2,  1, 16 );

        m_pLblCursor[0]->setVisible( true );
        m_pLblCursor[1]->setVisible( true );
        m_pLblCursor[2]->setVisible( true );
        m_pLblCursor[3]->setVisible( true );
    }
}

void CScreenW::NewScreen()
{
	int i;
		
	for( i = 0; i < 32*24; i++ ) m_Screen[i] = 0;
	
	UpdateScreen();
}

bool CScreenW::LoadScreen( QString fileName )
{
	int i;
	QString line;
	QFile hFile;
	
	
	hFile.setFileName( fileName );
	hFile.open( QIODevice::ReadOnly );
	QTextStream str( &hFile );

	if( hFile.atEnd() ) 
	{
		hFile.close();
		return false;
	}

	line = str.readLine();

	if( line != "SCREEN" )
	{
		hFile.close();
		return false;
	}

	for( i = 0; i < 32*24; i++ )
	{
		line = str.readLine();
		m_Screen[i] = line.toInt();
	}

	hFile.close();

	UpdateScreen();
	
	return true;
}

bool CScreenW::SaveScreen( QString fileName )
{
	int i;
	QFile hFile;
	

	hFile.setFileName( fileName );
	hFile.open( QIODevice::WriteOnly );

	QTextStream str( &hFile );
	
	str<<"SCREEN"<<endl;
	
	for( i = 0; i < 32*24; i++ ) str<<m_Screen[i]<<endl;

	hFile.flush();
	hFile.close();
	
	return true;
}

bool CScreenW::ExportScreenBin( QString fileName, int initX, int initY, int w, int h )
{
	int x, y;
	int addX, addY;
    int wi, he;
	QFile hFile;
	

	hFile.setFileName( fileName );
	hFile.open( QIODevice::WriteOnly );

	QDataStream str( &hFile );

	addX = m_pGrTilesBlockW->text().toLongLong();
	addY = m_pGrTilesBlockH->text().toLongLong();

    wi = initX + w;
    if( wi > 32 ) wi = 32;

    he = initY + h;
    if( he > 24 ) he = 24;

    for( y = initY; y < he; )

	{
        for( x = initX; x < wi; )
		{
			str<<(unsigned char)m_Screen[y*32+x];
			x+= addX;
		}
		y+= addY;
	}

	hFile.flush();
	hFile.close();
	
	return true;    
}

bool CScreenW::ExportScreenPNG( QString fileName )
{
    int h;
    int xT, yT;
    int i, y, x;
    int tileId;
    CTile tile;
    QImage image;


    image = QImage( 256, 192, QImage::Format_RGB32 );

    for( yT = 0, i = -1; yT < 192; yT+=8 )
    {
        for( xT = 0; xT < 256; xT+=8 )
        {
            i++;
            tileId = m_Screen[i];
            for( y = 0, tile = m_TilesBank[tileId%256][i/256]; y < 8; y++ )
            {
                for( x = 0; x < 8; x++ )
                {
                    image.setPixel( xT + x, yT + y, CSupportFuncs::COLORS_TABLE[tile.GetPixelColor(x, y)]);

                }
            }
        }
    }

    image.save( fileName );
}


bool CScreenW::ExportScreenBinPletter( QString fileName, int initX, int initY, int w, int h )
{
	int s;
	int x, y;
	int addX, addY;
    int wi, he;
	unsigned char buffer[256*3];

	addX = m_pGrTilesBlockW->text().toLongLong();
	addY = m_pGrTilesBlockH->text().toLongLong();
	s = 0;

    wi = initX + w;
    if( wi > 32 ) wi = 32;

    he = initY + h;
    if( he > 24 ) he = 24;

    for( y = initY; y < he; )
	{
        for( x = initX; x < wi; )
		{
			buffer[s] = (unsigned char)m_Screen[y*32+x];
			x+= addX;
			s++;
		}
		y+= addY;
	}

	PletterMain( s, buffer, fileName.toStdString() );

    return true; //TODO - 2
}

bool CScreenW::ExportScreenData( QString fileName, bool hexa, int initX, int initY, int w, int h )
{
	int addX, addY;
	int x, y;
    int wi, he;
	QFile hFile;
    QString tmp;
	

	hFile.setFileName( fileName );
	hFile.open( QIODevice::WriteOnly );

	QTextStream str( &hFile );
	
	str<<"SCREEN:"<<"\r\n"<<"db ";

	addX = m_pGrTilesBlockW->text().toLongLong();
	addY = m_pGrTilesBlockH->text().toLongLong();

    wi = initX + w;
    if( wi > 32 ) wi = 32;

    he = initY + h;
    if( he > 24 ) he = 24;

    for( y = initY; y < he; )
    {
        for( x = initX; x < wi; )
		{
            if( hexa ) str<<QString( "0x%1" ).arg( m_Screen[y*32+x], 0, 16 ).rightJustified( 4, ' ' );
            else str<<QString( "%1" ).arg( m_Screen[y*32+x] ).rightJustified( 3, ' ' );

            if( (y*32+x+1)%32 == 0 || x == ( wi - 1 ) )
			{
				str<<"\r\n";
                if( (y*32+x+1) != 256*3 && !( y == (he-1) && x == (wi-1) )) str<<"db ";
			}
            else if( !( x == (wi - 1) && y == (he - 1) ) ) str<<",";

			x+= addX;
		}
		y+= addY;
	}


	str<<"\r\n";

	hFile.flush();
	hFile.close();
	
	return true;
}

void CScreenW::NewTiles()
{
	int b, i;
	
	for( b = 0; b < 3; b++ )
	{
		for( i = 0; i < 256; i++ ) m_TilesBank[i][b] = CTile();
	}
	InitBanks();
}

bool CScreenW::LoadTiles( QString fileName )
{
	int i;
	int x, y, b;
	QString line;
	QFile hFile;
	
	
	hFile.setFileName( fileName );
	hFile.open( QIODevice::ReadOnly );
	QTextStream str( &hFile );

	if( hFile.atEnd() ) 
	{
		hFile.close();
		return false;
	}
	
	if( str.readLine() != "TILES" )
	{
		hFile.close();
		return false;
	}

	for( b = 0; b < 3; b++ )
	{
		line = str.readLine();

		if( line != QString( "BANK%1" ).arg( b ) )
		{
			hFile.close();
			return false;
		}
		for( i = 0; i < 256; i++ )
		{
			for( y = 0; y < 8; y++ ) m_TilesBank[i][b].put_BgColor( y, str.readLine().toInt() );
			
			for( y = 0; y < 8; y++ ) m_TilesBank[i][b].put_ForeColor( y, str.readLine().toInt() );
			
			for( y = 0; y < 8; y++ )
			{
				for( x = 0; x < 8; x++ ) m_TilesBank[i][b].put_Pixel( x, y, str.readLine().toInt() );
			}
		}
	}

	hFile.close();
	
	InitBanks();

	return true;
}

bool CScreenW::LoadTilesLibrary( QString fileName, int bankOr, int xOr, int yOr, int width, int height, int bankDest, int xDest, int yDest )
{
    int i;
    int vX, vY;
    int x, y, b;
    int dX, dY;
    QString line;
    QFile hFile;


    hFile.setFileName( fileName );
    hFile.open( QIODevice::ReadOnly );
    QTextStream str( &hFile );

    //TODO - 1 Indicar error
    if( hFile.atEnd() )
    {
        hFile.close();
        return false;
    }

    if( str.readLine() != "TILES" )
    {
        hFile.close();
        return false;
    }

    for( b = 0; b < 3; b++ )
    {
        line = str.readLine();

        if( line != QString( "BANK%1" ).arg( b ) )
        {
            hFile.close();
            return false;
        }

        for( i = 0; i < 256; i++ )
        {
            vX = i % 32;
            vY = i / 32;

            dX = vX - xOr + xDest;
            dY = vY - yOr + yDest;

            if( vX >= xOr && vX < ( xOr + width ) && vY >= yOr && vY < ( yOr + height ) && bankOr == b && dX >= 0 && dX < 32 && dY >=0 && dY < 8 )
            {
                qDebug()<<"CScreenW::LoadTilesLibrary dX="<<dX<<" dY="<<dY;
                for( y = 0; y < 8; y++ ) m_TilesBank[dY*32+dX][bankDest].put_BgColor( y, str.readLine().toInt() );

                for( y = 0; y < 8; y++ ) m_TilesBank[dY*32+dX][bankDest].put_ForeColor( y, str.readLine().toInt() );

                for( y = 0; y < 8; y++ )
                {
                   for( x = 0; x < 8; x++ ) m_TilesBank[dY*32+dX][bankDest].put_Pixel( x, y, str.readLine().toInt() );
                }
            }
            else
            {
                for( y = 0; y < 8*2; y++ ) str.readLine();
                for( y = 0; y < 8*8; y++ ) str.readLine();
            }
        }
    }

    hFile.close();

    InitBanks();

    return true;

}

bool CScreenW::SaveTiles( QString fileName )
{
	int i, b;
	int x, y;
	QFile hFile;
	

	hFile.setFileName( fileName );
	hFile.open( QIODevice::WriteOnly );

	QTextStream str( &hFile );
	
	str<<"TILES"<<endl;
	
	for( b = 0; b < 3; b++ )
	{
		str<<"BANK"<<b<<endl;
		
		for( i = 0; i < 256; i++ )
		{
			for( x = 0; x < 8; x++ ) str<<m_TilesBank[i][b].get_BgColor(x)<<endl;
			for( x = 0; x < 8; x++ ) str<<m_TilesBank[i][b].get_ForeColor(x)<<endl;
			for( y = 0; y < 8; y++ )
			{
				for( x = 0; x < 8; x++ ) str<<m_TilesBank[i][b].get_Pixel( x, y )<<endl;
			}
		}
	}
	
	hFile.flush();
	hFile.close();
	
	return true;
}

void CScreenW::GroupTiles()
{
	int blacked;
	int i, j, b;
	int index;
	CTile groupBank[256];


	for( b = 0; b < 3; b++ )
	{
		for( i = 0; i < 256; i++ ) groupBank[b] = CTile();

		for( i = 0, index = 0, blacked = false; i < 256; i++ )
		{
			if( !m_TilesBank[i][b].IsBlack() || !blacked )
			{
				if( m_TilesBank[i][b].IsBlack() ) blacked = true;

				groupBank[index] = m_TilesBank[i][b];

				for( j = 0; j < 256; j++ ) if( m_Screen[j+256*b] == i ) m_Screen[j+256*b] = index;

				index++;
			}
		}

		for( i = 0; i < 256; i++ ) m_TilesBank[i][b] = groupBank[i];
	}

	InitBanks();
}


void CScreenW::ExportTilesPNG( QString fileName )
{
    int h;
    int xT, yT;
    int i, y, x;
    CTile tile;
    QImage image;


    if( m_pGrOneBank->isChecked() ) h = 64;
    else h = 64*3;

    image = QImage( 256, h, QImage::Format_RGB32 );

    for( yT = 0, i = -1; yT < h; yT+=8 )
    {
        for( xT = 0; xT < 256; xT+=8 )
        {
            i++;
            for( y = 0, tile = m_TilesBank[i%256][i/256]; y < 8; y++ )
            {
                for( x = 0; x < 8; x++ )
                {
                    image.setPixel( xT + x, yT + y, CSupportFuncs::COLORS_TABLE[tile.GetPixelColor(x, y)]);

                }
            }
        }
    }

    image.save( fileName );
}


bool CScreenW::ExportTilesBin( QString fileName )
{
	int i, j;
	int b;
	QFile hFile;
	int nLoops;
	CDlgBankRange dlgBankRange;


	dlgBankRange.exec();
	
	if( dlgBankRange.result() == 0 ) //TODO - 1 MsgBox
	{
		return false;
	}
	
	hFile.setFileName( fileName + QString( ".til" ) );
	hFile.open( QIODevice::WriteOnly );

	if( m_pGrOneBank->isChecked() ) nLoops = 1;
	else nLoops = 3;

	QDataStream str( &hFile );
	
	for( b = 0; b < nLoops; b++ )
	{
		for( j = dlgBankRange.get_FromTile(); j <  dlgBankRange.get_ToTile() + 1; j++ )
		{
			if( dlgBankRange.get_BankOption() == 0 || dlgBankRange.get_BankOption() == (b + 1) )
			{
				for( i = 0; i < 8; i++ )
				{

					str<<(unsigned char)m_TilesBank[j][b].GetRowPattern( i );
				}
			}
		}
	}
	
	hFile.flush();
	hFile.close();
	
	hFile.setFileName( fileName + QString( ".col" ) );
	hFile.open( QIODevice::WriteOnly );

	QDataStream strCol( &hFile );
	
	for( b = 0; b < nLoops; b++ )
	{
		for( j = dlgBankRange.get_FromTile(); j < dlgBankRange.get_ToTile() + 1; j++ )
		{
			if( dlgBankRange.get_BankOption() == 0 || dlgBankRange.get_BankOption() == (b + 1) )
			{
				for( i = 0; i < 8; i++ )
				{
					strCol<<(unsigned char)m_TilesBank[j][b].GetRowColor( i );
				}
			}
		}
	}
	
	hFile.flush();
	hFile.close();
	
	return true;
}

void CScreenW::ExportTilesBinPletter( QString fileName )
{
	long sz;
    int i, b, j;
    int nLoops;
    unsigned char buffer[256*3*8];
	CDlgBankRange dlgBankRange;


	dlgBankRange.exec();

	if( dlgBankRange.result() == 0 ) //TODO - 1 MsgBox
	{
		return;
	}

    if( m_pGrOneBank->isChecked() ) nLoops = 1;
    else nLoops = 3;


	for( b = 0, sz = 0; b < nLoops; b++ )
    {
		for( j = dlgBankRange.get_FromTile(); j < dlgBankRange.get_ToTile() + 1; j++ )
        {
			if( dlgBankRange.get_BankOption() == 0 || dlgBankRange.get_BankOption() == (b + 1) )
			{
				//for( i = 0; i < 8; i++ ) buffer[b*256*8+j*8+i] = m_TilesBank[j][b].GetRowPattern( i );
				for( i = 0; i < 8; i++, sz++ ) buffer[sz] = m_TilesBank[j][b].GetRowPattern( i );
			}
        }
    }

	PletterMain( sz/*b*256*8*/, buffer, QString( fileName + QString( ".til" ) ).toStdString() );

	for( b = 0, sz = 0; b < nLoops; b++ )
    {
		for( j = dlgBankRange.get_FromTile(); j < dlgBankRange.get_ToTile() + 1; j++ )
        {
			if( dlgBankRange.get_BankOption() == 0 || dlgBankRange.get_BankOption() == (b + 1) )
			{
				for( i = 0; i < 8; i++, sz++ ) buffer[sz] = m_TilesBank[j][b].GetRowColor( i );
			}
        }
    }

	PletterMain( sz/*b*256*8*/, buffer, QString( fileName + QString( ".col" ) ).toStdString() );
}

bool CScreenW::ExportTilesData( QString fileName, bool hexa )
{
	int i, j;
	int b;
	QFile hFile;
	

	hFile.setFileName( fileName );
	hFile.open( QIODevice::WriteOnly );

	QTextStream str( &hFile );
	
	for( b = 0; b < 3; b++ )
	{
		str<<QString( "BANK_PATTERN_%1:").arg( b )<<endl;

		for( j = 0; j < 256; j++ )
		{
			str<<"db ";
			
			for( i = 0; i < 8; i++ ) 
			{
				if( hexa ) str<<QString( "0x%1" ).arg( m_TilesBank[j][b].GetRowPattern( i ), 0, 16 );
				else str<<m_TilesBank[j][b].GetRowPattern( i );

				if( i != 7 ) str<<", ";
			}
			str<<endl;
		}
	}
	
	str<<endl<<endl;
	
	for( b = 0; b < 3; b++ )
	{
		str<<QString( "BANK_COLOR_%1:").arg( b )<<endl;

		for( j = 0; j < 256; j++ )
		{
			str<<"db ";
			for( i = 0; i < 8; i++ ) 
			{
				if( hexa ) str<<QString( "0x%1" ).arg( m_TilesBank[j][b].GetRowColor( i ), 0, 16 );
				else str<<m_TilesBank[j][b].GetRowColor( i );

				if( i != 7 ) str<<", ";
			}
			str<<endl;
		}
	}
	
	hFile.flush();
	hFile.close();
	
	return true;
}

bool CScreenW::DeduceColorPalette( unsigned int color, unsigned int palette[16] ) {
    int i;
    unsigned int tmp;
    unsigned int paltmp[3];


    if( color >= 9000000 && color <= 17000000 ) { //RED 6, 8, 9

        paltmp[0] = palette[6];
        paltmp[1] = palette[8];
        paltmp[2] = palette[9];

        for( i = 2; i >=0; i-- ) {
            if( color == paltmp[i] ) break;

            if( color > paltmp[i] ) {
                tmp = paltmp[i];
                paltmp[i] = color;
                color = tmp;
                i = 3;
            }
        }

        palette[6] = paltmp[0];
        palette[8] = paltmp[1];
        palette[9] = paltmp[2];
    }

    return true; //TODO - -1 treure true

}

bool CScreenW::ImportTilesPNGAdv( QString fileName ) {
    int x, y, i, b;
    int fore, back;
    unsigned int color;
    unsigned int rawColor;
    QImage image;
    unsigned int palette[16];

    //Llegir fitxer i muntar paleta
    if( !image.load( fileName ) ) return false;
    for( i = 0; i < 16; i++ ) palette[i] = 0;

    for( y = 0; y < image.height(); y++ ) {

        for( x = 0; x < image.width(); x++) {
            color = image.pixel( x, y );
            if( color > 0xff000000 ) color -= 0xff000000; //Treu transparencia si hi ha

            DeduceColorPalette( color, palette );
        }

    }

    if( !image.load( fileName ) ) return false;

    if( image.width() < 256 || image.height() < 64 ) return false;

    for( b = 0; b < 3; b++ )
    {
        if( b > 0 && image.height() <= 64 ) break;

        for( y = 0; y < 8*8; y++ )
        {
            for( x = 0; x < 32; x++ )
            {
                fore = back = -1;

                for( i = 0; i < 8; i++ )
                {
                    rawColor = image.pixel( x*8+i, y+b*64 );
                    if( rawColor > 0xff000000 ) rawColor -= 0xff000000; //Treu transparencia si hi ha

                    color = GetColor( rawColor, palette );

                    if( fore == -1  )
                    {
                        fore = color;
                        m_TilesBank[(y/8)*32+x][b].put_ForeColor( y%8, fore );
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 1 );
                    }
                    else if( fore == color )
                    {
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 1 );
                    }
                    else if( back == -1 )
                    {
                        back = color;
                        m_TilesBank[(y/8)*32+x][b].put_BgColor( y%8, back );
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 0 );
                    }
                    else if( back == color )
                    {
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 0 );
                    }
                    else //Three colors on a row!
                    {
                        m_TilesBank[(y/8)*32+x][b].put_ForeColor( y%8, fore );
                    }
                }
            }
        }
    }

    InitBanks();

    return true;
}

bool CScreenW::ImportTiles( QString fileName, QString paletteFileName )
{
	int i;
	int color;
	int x, y, b;
	int fore, back;
	QImage image;
	unsigned int palette[16];
	
	
    if( paletteFileName == "" ) //Palette used by nMSXtiles
    {
        for( i = 0; i < 16; i++ ) palette[i] = CSupportFuncs::COLORS_TABLE[i];
    }
    else
    {
        if( !image.load( paletteFileName ) ) return false;

        if( image.width() < 16  ) return false;

        for( i = 0; i < 16; i++ ) palette[i] = (unsigned int )image.pixel( i, 0 );
    }

    if( !image.load( fileName ) ) return false;

    if( image.width() < 256 || image.height() < 64 ) return false;

    for( b = 0; b < 3; b++ )
    {
        if( b > 0 && image.height() <= 64 ) break;

        for( y = 0; y < 8*8; y++ )
        {
            for( x = 0; x < 32; x++ )
            {
                fore = back = -1;

                for( i = 0; i < 8; i++ )
                {
                    color = GetColor( image.pixel( x*8+i, y+b*64 ), palette );

                    if( fore == -1  )
                    {
                        fore = color;
                        m_TilesBank[(y/8)*32+x][b].put_ForeColor( y%8, fore );
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 1 );
                    }
                    else if( fore == color )
                    {
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 1 );
                    }
                    else if( back == -1 )
                    {
                        back = color;
                        m_TilesBank[(y/8)*32+x][b].put_BgColor( y%8, back );
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 0 );
                    }
                    else if( back == color )
                    {
                        m_TilesBank[(y/8)*32+x][b].put_Pixel( i, y%8, 0 );
                    }
                    else //Three colors on a row!
                    {
                        m_TilesBank[(y/8)*32+x][b].put_ForeColor( y%8, fore );
                    }
                }
            }
        }
    }

    InitBanks();

    return true;
}

bool CScreenW::ImportPolkaTiles( QString fileName )
{
	//7 bytes cabecera
	//256*8 Patterns
	//256*8 back|fore
	int i, b;
	int x, y;
	int value;
    unsigned char buffer[256*8];
    ifstream myFile( qPrintable( fileName ), ios::in | ios::binary );


	NewTiles();

    myFile.read ((char*)buffer, 7);
    if (!myFile) return false;

    myFile.read( (char*)buffer, 2048 );

	for( i = 0; i < 256; i++ )
	{
		for( y = 0; y < 8; y++ )
		{
			for( x = 0; x < 8; x++ )
			{
				value = ( buffer[ i*8 + y ] >> x ) & 0x1;
				m_TilesBank[i][0].put_Pixel( x, y, value );
			}
		}
	}

    myFile.read( (char*)buffer, 2048 );

	for( i = 0; i < 256; i++ )
	{
		for( y = 0; y < 8; y++ )
		{
			m_TilesBank[i][0].put_BgColor( y, ( buffer[i*8 + y] >> 4 ) & 0xF );
			m_TilesBank[i][0].put_ForeColor( y, ( buffer[i*8 + y] ) & 0xF );
		}
	}

	for( b = 0; b < 3; b++ ) for( i = 0; i < 32*8; i++ ) m_Screen[i+b*32*8]=i;

	InitBanks();

	return true;
}

bool CScreenW::ExportPolkaTiles( QString fileName )
{
	FILE *pFile;
	int i, y, x;
	unsigned char buffer[256*8];
	

	if( !( pFile = fopen( qPrintable( fileName ), "wb" ) ) ) return false;

	sprintf( (char*)buffer, "%s", "POLKA" );
	buffer[5] = 1;
	buffer[6] = 0;
	fwrite( buffer, sizeof( unsigned char ), 7, pFile );

	for( i = 0; i < 256; i++ )
	{
		for( y = 0; y < 8; y++ )
		{
			buffer[ i*8 + y ] = 0;

			for( x = 0; x < 8; x++ )
			{
				buffer[ i*8 + y ] |= ( m_TilesBank[i][0].get_Pixel( x, y )<<x );
			}
		}
	}

	fwrite( buffer, sizeof( unsigned char ), 2048, pFile );

	for( i = 0; i < 256; i++ )
	{
		for( y = 0; y < 8; y++ )
		{
			buffer[i*8+y] = ( (m_TilesBank[i][0].get_BgColor(y )<<4 ) | (m_TilesBank[i][0].get_ForeColor(y) ) );
		}
	}

	fwrite( buffer, sizeof( unsigned char), 2048, pFile );

	buffer[0] = 0; //Num of Palettes

	fwrite( buffer, sizeof( unsigned char ), 1, pFile );
//	[0][0][0][0]
	//[17][6]
	//[51][7]
	//[23][1][39][3]
	//[97][1][39][6][113][1]
	//[115][3][97][6]
	//[100][6][17][4][101][2][85][5][119][7]
	buffer[ 0] = buffer[1] = buffer[2] = buffer[3] = 0;
	buffer[ 4] = 17;	buffer[ 5] = 6;
	buffer[ 6] = 51;	buffer[ 7] = 7;
	buffer[ 8] = 23;	buffer[ 9] = 1;
	buffer[10] = 39;	buffer[11] = 3;
	buffer[12] = 97;	buffer[13] = 1;
	buffer[14] = 39;	buffer[15] = 6;
	buffer[16] =113;	buffer[17] = 1;
	buffer[18] =115;	buffer[19] = 3;
	buffer[20] = 97;	buffer[21] = 6;
	buffer[22] =100;	buffer[23] = 6;
	buffer[24] = 17;	buffer[25] = 4;
	buffer[26] =101;	buffer[27] = 2;
	buffer[28] = 85;	buffer[29] = 5;
	buffer[30] =119;	buffer[31] = 7;

	fwrite( buffer, sizeof( unsigned char ), 32, pFile );

	for( i = 0; i < 256; i++ ) buffer[i] = 1;

	fwrite( buffer, sizeof( unsigned char ), 256, pFile );

	fclose( pFile );

	return true;
}

void CScreenW::Fill1to255()
{
    int b;
    int i;


    for( b = 0; b < 3; b++ ) for( i = 0; i < 32*8; i++ ) m_Screen[i+b*32*8]=i;
    UpdateScreen();
}

int CScreenW::GetColor( unsigned int color, unsigned int palette[] )
{
	int i;
	
	for( i = 0; i < 16; i++ )
	{
		if( color == palette[i] ) return i;
	}
	//Color not in palette
	return 0;
}

void CScreenW::Close()
{
	m_Close = true;
	close();
}

void CScreenW::closeEvent( QCloseEvent *pEvent )
{
	if( m_Close ) pEvent->accept();
	else pEvent->ignore();
}

void CScreenW::OnOneBank()
{
	int i;
	
	
	m_pTabBank->setCurrentIndex( 0 );
		
	for( i = 0; i < 256; i++ )
	{
		m_TilesBank[i][1] = m_TilesBank[i][0];
		m_TilesBank[i][2] = m_TilesBank[i][0];
	}
	
	m_pTabBank->setTabEnabled( 1, !m_pGrOneBank->isChecked() );
	m_pTabBank->setTabEnabled( 2, !m_pGrOneBank->isChecked() );

	m_pGrBackgroundTiles1->setVisible( !m_pGrOneBank->isChecked() );
	m_pGrBackgroundTiles2->setVisible( !m_pGrOneBank->isChecked() );
	m_pGrLblBackgroundTiles1->setVisible( !m_pGrOneBank->isChecked() );
	m_pGrLblBackgroundTiles2->setVisible( !m_pGrOneBank->isChecked() );

	InitBanks();
}


void CScreenW::SetOneBank( bool value )
{
	m_pGrOneBank->setChecked( value );
	if( value ) OnOneBank();
}

bool CScreenW::GetOneBank()
{
	return m_pGrOneBank->isChecked();
}

