/* ==========================================================================
 * clPerfect11Game.js
 *
 * Written by Kostas Symeonidis
 * Copyright (c) 2009, CyLog Software
 * ==========================================================================
 * History:
 *
 * 29.Dec.2009  Renamed Perfect10 to Perfect11
 * 19.Dec.2009  Created library for new round of CyLog games
 * ==========================================================================
 *
 * ==========================================================================
 */

// ==========================================================================

// ---- Constants -----------------------------------------------------------

var MAX_IMAGES = 10;
var IMG_CLOSED = 99;

var imgclosed = new Image(48, 48);
imgclosed.src = "/static/games/p11img/closed.png";

// ---- Global Variables ----------------------------------------------------

var imgs = new Array();
var imgsInv = new Array();
var imgCount = 0;

// ---- Global initialisation -----------------------------------------------

var imgsFname = new Array();
var imgsFnameInv = new Array();

var tiles = new Array();  // the actual tiles of the board
var sig = new Array();    // the signature of the solution gradually being built

var o1 = IMG_CLOSED;
var o2 = IMG_CLOSED;
var inverse = IMG_CLOSED;
var state = 0;
var score = 0;
var visible = 0;
var gameStarted = false;
var starttime;
var prevtime;
var endtime;

var lblScore;     // label for displaying current score
var lblTime;      // displays the time
var edtScore;     // hidden form element to submit the score
var edtDuration;  // hidden form element to submit the duration
var edtSig;       // hidden form element to submit the signature
var ajaxMsg;      // ajax keep alive message

var signature;    // being built up as we reveal cards

/*
 * Returns the current time in milliseconds
 */
function timeInMillis ()
{
    var now = new Date();
    return now.getTime();
}

/*
 * Allocates and sets up all images from 0..imgCount-1
 */
function setupImageFilenames ()
{
    for (var i = 0; i < MAX_IMAGES; i++)
    {
        imgs[i] = new Image(48, 48);
        imgsFname[i] = lPadZero(i + 1, 2) + ".png";
        imgs[i].src = "/static/games/p11img/" + imgsFname[i];

        imgsInv[i] = new Image(48, 48);
        imgsFnameInv[i] = "_" + lPadZero(i + 1, 2) + ".png";
        imgsInv[i].src = "/static/games/p11img/" + imgsFnameInv[i];
    }
}

/*
 * Gets the MAX_IMAGES filenames and mixes them up 100 times
 */
function randomMixUpImages ()
{
    // setup all the image filenames
    for (var i = 0; i < imgCount / 2; i++)
    {
        tiles[i * 2] = Math.floor(Math.random() * MAX_IMAGES);
        tiles[i * 2 + 1] = MAX_IMAGES - 1 - tiles[i * 2];
    }

    var h1,h2,h3;
    for (i = 0; i < 300; i++)
    {
        h1 = Math.floor(Math.random() * imgCount);
        h2 = Math.floor(Math.random() * imgCount);
        if (h1 != h2)
        {
            h3 = tiles[h1];
            tiles[h1] = tiles[h2];
            tiles[h2] = h3;
        }
    }

    // show the images and initialise the Signature
    for (i = 0; i < imgCount; i++)
    {
        document.images["bb" + i].src = imgs[tiles[i]].src;
        sig[i] = IMG_CLOSED;
    }
}

/*
 * Sets up a Perfect11 game for the given Rows and Columns
 */
function setupPerfect11Game ( a_iRows, a_iCols )
{
    imgCount = a_iRows * a_iCols;

    setupImageFilenames();
    randomMixUpImages();

    // page placeholders that will be updating
    lblScore = document.getElementById("lblScore").firstChild;
    lblTime = document.getElementById("lblTime").firstChild;
    edtScore = document.getElementById("edtScore");
    edtDuration = document.getElementById("edtDuration");
    edtSig = document.getElementById("edtSig");

    ajaxMsg = document.getElementById("ajaxMsg");

    // start score
    score = 0;

    var s = "";
    for (var i = 0; i < imgCount; i++)
    {
        if (i != 0)
            s += ", ";
        s += tiles[i] + "-" + imgsFname[tiles[i]].substr(0, 2);
    }
    edtSig.value = "[" + s + "]";
}

function buildSignature ()
{
    var s = "";
    for (var i = 0; i < imgCount; i++)
    {
        if (i != 0)
            s += ", ";
        s += sig[i] + "-" + imgsFname[sig[i]].substr(0, 2);
    }
    edtSig.value = s;
}

function hideimages ()
{
    document.images["bb" + o1].src = imgclosed.src;
    document.images["bb" + o2].src = imgclosed.src;
    state = 0;
}

function imageClick ( btn )
{
    if (!gameStarted)
    {
        gameStarted = true;
        starttime = timeInMillis();
        setInterval("displayTime()", 1000);
    }

    if ((tiles[btn] != IMG_CLOSED ) && (state != 2))
    {
        // do Ajax call
        ajaxMsg.value = btn + "-" + tiles[btn];
        invoke($('form')[1], 'ajax', '#replaceWithAjax');

        // count the score
        score++;
        lblScore.nodeValue = score;

        // increase state (how many images are open)
        state++;
        if (state == 1)
        {
            o1 = btn;
            document.images["bb" + btn].src = imgsInv[tiles[btn]].src;
            inverse = btn;
        }
        if (state == 2)
        {
            if (btn == o1)
            {
                state = 1;
                return;
            }

            o2 = btn;
            document.images["bb" + btn].src = imgsInv[tiles[btn]].src;
            if (tiles[o1] + tiles[o2] == MAX_IMAGES - 1)
            {
                document.images["bb" + o1].src = imgclosed.src;
                document.images["bb" + o2].src = imgclosed.src;
                sig[o1] = tiles[o1];
                sig[o2] = tiles[o2];
                tiles[o1] = IMG_CLOSED;
                tiles[o2] = IMG_CLOSED;
                state = 0;
                visible += 2;
                if (visible == imgCount)
                {
                    endtime = timeInMillis();
                    gameStarted = false;
                    edtScore.value = score;
                    edtDuration.value = endtime - starttime;
                    buildSignature();

                    // Now submit the form 
                    submit();
                }
            }
            else
            {
                state = 1;
                if (inverse != IMG_CLOSED)
                {
                    document.images["bb" + inverse].src = imgs[tiles[inverse]].src;
                }
                document.images["bb" + btn].src = imgsInv[tiles[btn]].src;
                inverse = btn;
                o1 = btn;
            }
        }
    }
}

/*
 * Displays the running clock at the HTML node with id "lblTime"
 */
function displayTime ()
{
    if (gameStarted)
    {
        var timeElapsed = (timeInMillis() - starttime) / 1000;
        var minutes = Math.floor(timeElapsed / 60);
        var seconds = Math.floor(timeElapsed % 60);

        lblTime.nodeValue = lPadZero(minutes, 2) + ":" + lPadZero(seconds, 2);
    }
    else
    {
        timeElapsed = (endtime - starttime);
        minutes = Math.floor(timeElapsed / 60000);
        seconds = Math.floor(timeElapsed / 1000) % 60;
        var millis = Math.floor(timeElapsed % 1000);
        lblTime.nodeValue = lPadZero(minutes, 2) + ":" + lPadZero(seconds, 2) + "." + lPadZero(millis, 3);
    }
}

function submit ()
{
    document.forms[0].submit();
}

