/**
 * Matching game
 * Serge Dolgov (C) 2002
 * studio.quazzle.com
 */

function QMatchGame_run() {
    this.reset();
    this.load();
}

function QMatchGame_reset() {
    if (this._TID) {
        clearTimeout(this._TID);
        this._TID = null;
    }
    this.clicks = 0;
    this.matched = 0;
    if (this.onScore) this.onScore(this.clicks, this.matched);
}

function QMatchGame_show(show, j) {
    if (show && this.loaded) {
        for (var i=0; i<this.cells.length; i++) this.cells[i].show(true);
    } else if (!show) {
        j = j || 0;
        var dw = this.hsize - j * 2;
        if (dw > 0) {
            var i = j;
            for (var n=0; n<this.vsize; n++) {
                this.cells[i].show(false);
                i += this.hsize;
            }
            if (dw > 1) {
                i = this.hsize - j - 1;
                for (n=0; n<this.vsize; n++) {
                    this.cells[i].show(false);
                    i += this.hsize;
                }
            }
            setTimeout(this.name + ".show(false," + (j + 1) + ")", 200);
        }
    }
}

function QMatchGame_handleClick(type) {
    with (this.parent) {
        if (!this.busy) {
            this.parent.clicks ++;
            if (type == (opencell && opencell.type)) {
                this.parent.opencell = null;
                this.parent.matched ++;
            } else {
                if (opencell) opencell.show(false);
                this.parent.opencell = this;
            }
            if (this.parent.onScore) onScore(clicks, matched);
            if (this.parent.onGameOver && (matched >= cells.length/2)) {
                onGameOver(clicks, matched);
                this.parent.over = true;
            }
        }
    }
}

function QMatchGame_load() {
    with (this) {
        this.loaded = this.over = false;
        this.busy = true;
        var len = Math.floor(cells.length / 2);
        var sh = Math.floor(Math.random() * (heapsize - len + .999));
        var i;
        for (var j=sh, i=0; j<(sh + len); j++) {
            cells[i++].load(heap1 + j + heapext, j + 1);
            cells[i++].load((heap2 || heap1) + j + heapext, j + 1);
        }
        trackLoading();
    }
}

function QMatchGame_trackLoading(tick) {
    this._TID = null;
    tick = tick || 0;
    if (tick < 300) {
        var count = 0;
        if (tick) {
            for (var j=0; j<this.cells.length; j++) count += this.cells[j].face.complete && 1;
            if (this.onLoading) this.onLoading(count);
        }
        if (count < this.cells.length) {
            this._TID = setTimeout(this.name + ".trackLoading(" + (tick + 1) + ")", 1000);
        } else {
            this.loaded = true;
            this.shuffle(this.animated);
        }
    } else {
        if (this.onError) this.onError("Internet connection lost.");
    }
}

function QMatchGame_shuffle(animated) {
    var cnt = this.cells.length * 5;
    if (animated) {
        this.show(true);
        this.swapCells(true, cnt);
    } else {
        for (var j=cnt; j>=0; j--) this.swapCells(false, j);
    }
}

function QMatchGame_swapCells(animated, count) {
    this._TID = null;
    var mult = this.cells.length - .001;
    var i = null;
    var j = null;
    while (i == j) {
        i = this.cells[Math.floor(Math.random() * mult)];
        j = this.cells[Math.floor(Math.random() * mult)];
    }
    j.swap(i);
    if (animated) {
        j.show(true);
        i.show(true);
        if (count) this._TID = setTimeout(this.name + ".swapCells(true, " + (count - 1) + ")",
            (333 / count + 10));
    }
    if (!count) {
        this.busy = false;
        this.show(false);
        if (this.onGameStart) this.onGameStart();
    }
}

function QMatchGame(parent, name, hsize, vsize, cellwidth, cellheight, heap1, heap2, heapsize, ext) {
    this.init(parent, name);
    this.hsize = hsize || 0;
    this.vsize = vsize || 0;
    this.heapsize = heapsize;
    this.heapext = ext || ".gif";
    this.heap1 = heap1 || null;
    this.heap2 = heap2 || null;
    this.cells = new Array(hsize * vsize);
    this.loaded = false;
    this.animated = true;  // animation effects
    this.busy = false;
    this.over = false;
    this.opencell = null;
    this.clicks = 0;
    this.matched = 0;
    this.back = new Image(cellwidth, cellheight);
    this.back.src = heap1 + "x.gif";
    this.load = QMatchGame_load;
    this.show = QMatchGame_show;
    this.trackLoading = QMatchGame_trackLoading;
    this.shuffle = QMatchGame_shuffle;
    this.swapCells = QMatchGame_swapCells;
    this.handleClick = QMatchGame_handleClick;
    this.reset = QMatchGame_reset;
    this.run = QMatchGame_run;    
    with (document) {
        var k = this.cells.length;
        if ((k/2 <= heapsize) && !(k % 2)) {
            writeln('<table class="matchgame" border="0" width="' + (hsize * cellwidth) + '" height="' + (vsize * cellheight) + '" cellspacing="0" cellpadding="0">');
            for (var j=0, k=0; j<vsize; j++) {
                writeln('<tr>');
                for (var i=0; i<hsize; i++, k++) {
                    write('<td width="' + cellwidth + '" height="' + cellheight + '">');
                    var cell = new QMatchCell(this, "cells[" + k + "]", cellwidth, cellheight, this.back, heap1 + "_.gif");
                    cell.onClick = this.handleClick;
                    this.cells[k] = cell;
                    writeln('</td>');
                }
                writeln('</tr>');
            }
            writeln('</table>');
        } else {
            write('Invalid game parameters');
        }
    }
}
QMatchGame.prototype = new QControl();