// BOSSENX.CPP
//
// Copyright (c) 1998 Symbian Ltd.  All rights reserved.
//

#include "bossenx.h"
#include <oplerr.h>

#pragma data_seg(".E32_UID")
__WINS_UID(0,KUidOpxValue,KUidOpxBossEnxValue)
#pragma data_seg()

                                                          
////////////////////////////////////////////////////////////////////////////////////////////
// CBossEnx class : derives from COpxBase
//
// The language extension procedures provided by this OPX
//

// initialize state
	void CBossEnx::SetFullyOrdered() 
	// all tiles in order
		{
		iBossPuzzle.SetFullyOrdered();
		iOplAPI.Push(0.0);
		}

	void CBossEnx::SetBossOrdered()
	// 14 and 15 swapped
		{
		iBossPuzzle.SetBossOrdered();
		iOplAPI.Push(0.0);
		
		}
	// inquiry
	void CBossEnx::IsFullyOrdered() const
		{
		if(iBossPuzzle.IsFullyOrdered())
			{
			iOplAPI.Push(KTrue);
			}
		else
			{
			iOplAPI.Push(KFalse);
			}

		}
	void CBossEnx::IsBlank() const
		{
		TInt32 col = iOplAPI.PopInt32();
		TInt32 row = iOplAPI.PopInt32();
		if(iBossPuzzle.IsBlank(row, col))
			{
			iOplAPI.Push(KTrue);
			}
		else
			{
			iOplAPI.Push(KFalse);
			}
		}

	void CBossEnx::Tile()
		{
		TInt col = iOplAPI.PopInt32();
		TInt row = iOplAPI.PopInt32();
		TInt32 num = iBossPuzzle.Tile(row, col);
		iOplAPI.Push(num);
		}

	void CBossEnx::LocateTile()
		{
		TInt32* col = iOplAPI.PopPtrInt32();
		TInt32* row = iOplAPI.PopPtrInt32();
		TInt32 num = iOplAPI.PopInt32();
		TInt newcol, newrow;
		iBossPuzzle.LocateTile(num, newrow, newcol);
		iOplAPI.PutLong(col,newcol);
		iOplAPI.PutLong(row,newrow);
		iOplAPI.Push(0.0);
		}

	void CBossEnx::LocateBlank()
		{
		TInt32* col = iOplAPI.PopPtrInt32();
		TInt32* row = iOplAPI.PopPtrInt32();
		TInt newcol, newrow;
		iBossPuzzle.LocateBlank(newrow, newcol);
		iOplAPI.PutLong(col,newcol);
		iOplAPI.PutLong(row,newrow);
		iOplAPI.Push(0.0);
		}

	// whether various moves are possible
	void CBossEnx::CanMove() 
		{
		TInt16 move = iOplAPI.PopInt16();
		if(iBossPuzzle.CanMove((TBossPuzzle::TMoveType) move))
			{
			iOplAPI.Push(KTrue);
			}
		else
			{
			iOplAPI.Push(KFalse);
			}
		}

	void CBossEnx::CanMoveFrom()
		{
		TInt32 col = iOplAPI.PopInt32();
		TInt32 row = iOplAPI.PopInt32();
		if(iBossPuzzle.CanMove(row, col))
			{
			iOplAPI.Push(KTrue);
			}
		else
			{
			iOplAPI.Push(KFalse);
			}
		}

	void CBossEnx::CanMoveType()
		{
		TInt32 col = iOplAPI.PopInt32();
		TInt32 row = iOplAPI.PopInt32();
		iOplAPI.Push((TInt16)iBossPuzzle.CanMoveType(row, col));
		}

	// moving - these functions panic if impossible
	void CBossEnx::MoveFrom()
		{
		TInt32 col = iOplAPI.PopInt32();
		TInt32 row = iOplAPI.PopInt32();
		iBossPuzzle.Move(row, col);
		iOplAPI.Push(0.0);
		}

	void CBossEnx::Move()
		{
		TInt16 move = iOplAPI.PopInt16();
		iBossPuzzle.Move((TBossPuzzle::TMoveType) move);
		iOplAPI.Push(0.0);
		}

// The members of CBossEnx which are not language extension procedures
//
CBossEnx::CBossEnx(OplAPI& aOplAPI) : COpxBase(aOplAPI)
    {
     __DECLARE_NAME(_S("CBossEnx"));
    }


CBossEnx* CBossEnx::NewL(OplAPI& aOplAPI)
    {
    CBossEnx* This=new(ELeave) CBossEnx(aOplAPI);
    CleanupStack::PushL(This);
    This->ConstructL();
    CleanupStack::Pop();
    return This;
    }


void CBossEnx::ConstructL()
    {
	// Do whatever is required to constuct any component members you have in CBossEnx
	// ...

    } 

CBossEnx::~CBossEnx()
    {
    Dll::FreeTls();		// Required so that Tls is set to zero on unloading the OPX in UNLOADM
    }

// COpxBase implementation
//
void CBossEnx::RunL(TInt aProcNum)
// Run a language extension procedure
	{
	switch (aProcNum)
		{
	case ESetFullyOrdered:
		SetFullyOrdered();
		break;
	case ESetBossOrdered:
		SetBossOrdered();
		break;
	case EIsFullyOrdered:
		IsFullyOrdered();
		break;
	case EIsBlank:
		IsBlank();
		break;
	case ETile:
		Tile();
		break;
	case ELocateTile:
		LocateTile();
		break;
	case ELocateBlank:
		LocateBlank();
		break;
	case ECanMove:
		CanMove();
		break;
	case ECanMoveFrom:
		CanMoveFrom();
		break;
	case ECanMoveType:
		CanMoveType();
		break;
	case EMove:
		Move();
		break;
	case EMoveFrom:
		MoveFrom();
		break;
	default:
		User::Leave(KOplErrOpxProcNotFound);
		}
	}

TBool CBossEnx::CheckVersion(TInt aVersion)
// To check whether the opx is a compatible version
// *** Change as required ***
	{
	if ((aVersion & 0x0f00)>(KOpxBossEnxVersion & 0xf00))	// major version must be <= OPX's version
		return EFalse; // bad version
	else
		return ETrue; // ok
	}


EXPORT_C COpxBase* NewOpxL(OplAPI& aOplAPI)
// Creates a COpxBase instance as required by the OPL runtime
// This object is to be stored in the OPX's TLS as shown below
	{
	CBossEnx* tls=((CBossEnx*)Dll::Tls());
	if (tls==NULL)		// tls is NULL on loading an OPX DLL (also after unloading it)
		{
        tls=CBossEnx::NewL(aOplAPI);
		CleanupStack::PushL(tls);
	    TInt ret=Dll::SetTls(tls);
		User::LeaveIfError(ret);
		CleanupStack::Pop();	// tls
        }
    return (COpxBase *)tls;
	}

GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
//
// DLL entry point
//
	{
	return(KErrNone);
	}

/* End of $Workfile:   BOSSENX.CPP  $ */
 
