// BOSSVIEW.CPP
//
// Copyright (c) 1998 Symbian Ltd.  All rights reserved.
//

#include "bosseng.h"
#include "bossview.h"

#include <coemain.h>

EXPORT_C CBossView::CBossView(const CCoeControl* aParent, const TRect& aRect, TBossPuzzle* aModel)
	: iModel(aModel), iParent(aParent), iOfferedRect(aRect)
	{
	}

EXPORT_C CBossView::CBossView()
	{ // private, so never gets invoked; required for DLL goodness reasons
	}

EXPORT_C void CBossView::ConstructL()
	{
	//constant declaration
	_LIT(KFontArial,"Arial");
	// create window
	CreateWindowL(iParent);
	// construct font for messages
    TFontSpec spec(KFontArial,10*20);
    iTileFont=iCoeEnv->CreateScreenFontL(spec);
	// set rectangle to prescription
	SetRectL(iOfferedRect);
	// go for it
	ActivateL();
	}

CBossView::~CBossView()
	{
	iCoeEnv->ReleaseScreenFont(iTileFont);
	}

const TInt KBossViewTileSize=21; // outside dimension of tile
const TInt KBossViewTileSpacing=2; // blank pixels between adjacent tiles
const TInt KBossViewBoardBorderWidth=3; // in addition to four tiles and five blanks
const TInt KBossViewTileBorderWidth=1; // takes away from tile space to give less for number

void CBossView::GetBoardRect(TRect& aRect) const
	{
	TInt boardSize=4*KBossViewTileSize+5*KBossViewBoardBorderWidth+1;
	aRect=TRect(Rect().iTl+TPoint(15,15), TSize(boardSize,boardSize));
	}

void CBossView::DrawBoard() const
	{
	CWindowGc& gc=SystemGc();
	TRect boardRect;
	GetBoardRect(boardRect);
	gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
	gc.SetPenColor(KRgbBlack);
	gc.DrawRect(boardRect);
	}

void CBossView::GetTileRect(TRect& aRect, TInt aRow, TInt aCol) const
	{
	GetBoardRect(aRect);
	TInt dx=KBossViewTileSpacing+1+aCol*(KBossViewTileSpacing+1+KBossViewTileSize);
	TInt dy=KBossViewTileSpacing+1+aRow*(KBossViewTileSpacing+1+KBossViewTileSize);
	aRect=TRect(aRect.iTl+TPoint(dx,dy), TSize(KBossViewTileSize+1, KBossViewTileSize+1));
	}

void CBossView::DrawTile(TInt aRow, TInt aCol) const
	{ 
	//constant declaration
	_LIT(KNumFormat,"%d");

	// tile or blank
	// board dimensions
	TRect tileRect;
	GetTileRect(tileRect, aRow, aCol);
	// tile or blank
	CWindowGc& gc=SystemGc();
	if (iModel->Tile(aRow,aCol)!=0)
		{
		// draw rectangle
		gc.SetPenStyle(CGraphicsContext::ESolidPen);
		gc.DrawRect(tileRect);
		// draw number
		tileRect.Shrink(1,1);
		TInt ascent=
				(tileRect.Height() - iTileFont->HeightInPixels())/2 +
					iTileFont->AscentInPixels();
		// draw text in rectangle
   		gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
		gc.UseFont(iTileFont);
		TBuf<2> number;
		number.Format(KNumFormat,TInt(iModel->Tile(aRow,aCol)));
		gc.DrawText(number, tileRect, ascent, CGraphicsContext::ECenter, 0);
		}
	else
		{
		gc.SetPenStyle(CGraphicsContext::ENullPen);
		gc.DrawRect(tileRect);
		}
	}

void CBossView::Draw(const TRect& /* aRect */) const
	{
	CWindowGc& gc=SystemGc();
	gc.DrawRect(Rect()); // clear background
	DrawBoard(); // draw board
	// draw each tile
	for (TInt row=0; row<4; row++)
		{
		for (TInt col=0; col<4; col++)
			{
			DrawTile(row, col);
			}
		}
   	}

EXPORT_C void CBossView::MoveTile(TInt aOldBlankRow, TInt aOldBlankCol, TInt aNewBlankRow, TInt aNewBlankCol) const
	{
	// find bounding rectangle of old and new
	TRect oldBlankRect;
	GetTileRect(oldBlankRect, aOldBlankRow, aOldBlankCol);
	TRect newBlankRect;
	GetTileRect(newBlankRect, aNewBlankRow, aNewBlankCol);
	TRect invalidRect=oldBlankRect;
	invalidRect.BoundingRect(newBlankRect);
	// draw-now sequence, with invalid region set to bounding rectangle
	ActivateGc();
	Window().Invalidate(invalidRect);
	Window().BeginRedraw(invalidRect);
	DrawTile(aOldBlankRow, aOldBlankCol); // no longer blank
	DrawTile(aNewBlankRow, aNewBlankCol); // now blank
	Window().EndRedraw();
	DeactivateGc();
	}

