/*

Quicktetris published by Thomas Kjeldahl Nilsson under 
Creative Commons Attribution 3.0 license.
License terms: http://creativecommons.org/licenses/by/3.0/

*/

var Test = {

    runSuite: function() {
        // Call all methods/testcases in suite
        for (var testFunc in this.Suite) {
            if (this.Suite.hasOwnProperty(testFunc)) { // Don't call any inherited methods
                try {
                    this.Suite[testFunc]();
                }
                catch(err) {
                    alert(testFunc + "() failed: " + err);
                    return;
                }
            }
        }

        Graphics.drawString("--All tests in suite passed--", 400, 400);
    },

    Suite: {

        // Add test cases here
        testAsserts: function() {
            assertTrue(2 === 2, "This should never fail");
            assertFalse(2 === 3, "This should always fail");
        },

        testArrDimensions: function() {
            var width = 3;
            var height = 2;
            var initValue = "x";
            var arr = get2dArray(width, height, initValue);

            assertTrue(arr.getWidth() === width, "Width of array not expected length");
            assertTrue(arr.getHeight() === height, "Height of array not expected length");

            for (var x in arr) {
                if (arr.hasOwnProperty(x)) { // Don't call any inherited methods
                    assertTrue(arr[x].length === height, "Height of array not expected length");
                }
            }
        },

        testArrEach: function() {
            var arr = [2, 4, 5, 2];
            var length = arr.length;

            var elementsVisited = 0;
            arr.each(function(element) {
                assertTrue(element !== null, "Expected all elements to be non-null");
                elementsVisited++;
            });

            assertTrue(elementsVisited === length, "Didn't visit " + length + " elements as expected");
        },

        testArrEach2d: function() {
            var width = 3;
            var height = 2;
            var initValue = "x";
            var arr = get2dArray(width, height, initValue);

            var elementsVisited = 0;
            arr.each(function(element) {
                assertTrue(element === initValue, "Not all slots in array was set to " + initValue);
                elementsVisited++;
            });

            assertTrue(elementsVisited === (width * height), "Didn't visit " + (width * height) + " elements as expected");
        },

        testArrEachRow: function() {
            var width = 3;
            var height = 4;
            var initValue = "x";
            var arr = get2dArray(width, height, initValue);

            var rowsVisited = 0;
            arr.eachRowWithIndex(function(row) {
                assertTrue(row.length === width, "Expected row to be " + width + " elements long");
                rowsVisited++;
            });

            assertTrue(rowsVisited === height, "Didn't get " + height + " rows as expected");
        },

        testArrMap: function() {
            var width = 2;
            var height = 2;
            var initValue = "2";
            var arr = get2dArray(width, height, initValue);

            var mappedArr = arr.map(function(element) {
                return element * 2;
            });

            var elementsVisited = 0;
            mappedArr.each(function(element) {
                assertTrue(element === initValue * 2, "Not all slots in mapped array were transformed to new value");
                elementsVisited++;
            });

            assertTrue(elementsVisited === width * height, "Mapped array not same size as original array");
        }

    },

    // Graphical tests

    testDrawSingleSquare: function() {
        Graphics.clearGameContainer();
        var square = Graphics.createRectangleDiv("purple", 400, 400, 20, 20);
    },

    testDetectKeys: function() {
        Graphics.clearGameContainer();
        Graphics.drawString("Press a key", 400, 400);

        // Register key mapping
        setKeyReaction(function(keyCode) {
            switch (keyCode) {
            case DIR_KEY_DOWN:
                Graphics.drawString("down key pressed", 400, 400);
                break;
            case DIR_KEY_UP:
                Graphics.drawString("up key pressed", 400, 400);
                break;
            case DIR_KEY_LEFT:
                Graphics.drawString("left key pressed", 400, 400);
                break;
            case DIR_KEY_RIGHT:
                Graphics.drawString("right key pressed", 400, 400);
                break;
            case SPACE_KEY:
                Graphics.drawString("space key pressed", 400, 400);
                break;
            default:
                Graphics.drawString('KeyCode ' + keyCode + ' not handled by test case.', 400, 400);
            }
        });
    },

    testDrawPlayingField: function() {
        Graphics.clearGameContainer();
        Field.init("magenta", "blue", 400, 100); // Set up field state
        Field.tileOn(0, 0);
        Field.tileOn(1, 1);
    },

    testMoveSquare: function() {
        Graphics.clearGameContainer();

        var dronePos = {
            x: 400,
            y: 400
        };
        var drone = null;

        function moveDrone(dx, dy) {
            dronePos.x += dx;
            dronePos.y += dy;

            sq.style.left = dronePos.x;
            sq.style.top = dronePos.y;
        }

        // Create the square graphic
        var sq = Graphics.createRectangleDiv("green", dronePos.x, dronePos.y, 20, 20);

        // Register key mapping
        setKeyReaction(function(keyCode) {
            switch (keyCode) {

            case DIR_KEY_DOWN:
                moveDrone(0, 5);
                break;
            case DIR_KEY_UP:
                moveDrone(0, -5);
                break;
            case DIR_KEY_LEFT:
                moveDrone( - 5, 0);
                break;
            case DIR_KEY_RIGHT:
                moveDrone(5, 0);
                break;
            default:
                //KeyCode not handled by test case
                Graphics.drawString('Use direction keys to move', 400, 400);
            }
        });
    },

    testPieceCollision: function() {
        Graphics.clearGameContainer();

        Field.init("magenta", "blue", 400, 100);
        Piece.init();

        // Register key mapping
        setKeyReaction(function(keyCode) {
            switch (keyCode) {
            case DIR_KEY_DOWN:
                Piece.moveDown(15);
                break;
            case DIR_KEY_UP:
                Piece.moveUp(15);
                break;
            case DIR_KEY_LEFT:
                Piece.moveLeft(Piece.State.tileWidth);
                break;
            case DIR_KEY_RIGHT:
                Piece.moveRight(Piece.State.tileWidth);
                break;
            case NUM_KEY_ONE:
                Piece.toggleSquareShape();
                break;
            case NUM_KEY_TWO:
                Piece.toggleLineShape();
                break;
            case NUM_KEY_THREE:
                Piece.toggleTeeShape();
                break;
            case NUM_KEY_FOUR:
                Piece.toggleRHookShape();
                break;
            case NUM_KEY_FIVE:
                Piece.toggleLHookShape();
                break;
            case NUM_KEY_SIX:
                Piece.toggleRightLShape();
                break;
            case NUM_KEY_SEVEN:
                Piece.toggleLeftLShape();
                break;
            case SPACE_KEY:
                Piece.rotate(true);
                break;
            default:
                Graphics.drawString('Direction keys moves, space rotates, 1-5 changes piece type', 400, 400);
            }
        });
    },

    testPlaySound: function() {
	Sound.playLandingSound();
    },

    testPlaySoundLooped: function() {
	Sound.playLoopedLandingSound();
    },

    testPlayMusic: function() {
	Sound.playAmbientMusic();
    },

    testExplodeAnimation: function() {
        Graphics.clearGameContainer();
        var square = Graphics.createRectangleDiv("black", 400, 400, 100, 100);
        $(square).hide("explode", {},
        1000);
    }

};