var ship = {
    x: 10,
    y: 10,
    a: 0,
    s: 2,
    exploid: null,
    isPlayer: true
};

var gameStarted = false;

var enemyShips = [];

var bullets = [];

var stars = [];
var rocks = [];

var firstBlood = false;
var minionsDead = false;

var updateCounter = 0;
var milliseconds = 0;
var shotCount = 0;
var botDestroedScope = 0;

var isMovingLeft = false;
var isMovingRight = false;

window.requestAnimFrame = (function (callback) {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function (callback) {
        window.setTimeout(callback, 1000 / 25);
    };
})();

function drawShip(ship, context) {

    if (ship.exploid === null) {
        if (ship.isPlayer) {
            drawPlayerShip(ship, context);
        }
        else {
            drawEnemyShip1(ship, context, ecolors[ship.model]);
        }
    }
    else {
        ship.exploid++;

        if (ship.exploid < 200) {

            context.beginPath();
            context.arc(ship.x, ship.y, ship.exploid / 10, 0, 2 * Math.PI, false);
            context.arc(ship.x + 8, ship.y + 4, ship.exploid / 20, 0, 2 * Math.PI, false);
            context.arc(ship.x - 10, ship.y - 2, ship.exploid / 25, 0, 2 * Math.PI, false);
            context.fillStyle = 'red';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = '#003300';
            context.stroke();
        }
    }
}

function drawPlayerShip(ship, context) {

    context.moveTo(ship.x, ship.y);
    for (var i = 0; i < 7; i++) {
        var a1 = (Math.PI * 2) * i / 6;
        context.lineTo(Math.cos(ship.a + a1) * 10 + ship.x, Math.sin(ship.a + a1) * 10 + ship.y);
    }
    context.fillStyle = '#886666';
    context.fill();
    context.lineWidth = 1;
    context.strokeStyle = 'black';
    context.stroke();


    context.beginPath();
    context.moveTo(Math.cos(ship.a) * 10 + ship.x, Math.sin(ship.a) * 10 + ship.y);
    context.lineTo(Math.cos(ship.a - (Math.PI + Math.PI / 10)) * 15 + ship.x, Math.sin(ship.a - (Math.PI + Math.PI / 10)) * 15 + ship.y);
    context.lineTo(Math.cos(ship.a + (Math.PI + Math.PI / 10)) * 15 + ship.x, Math.sin(ship.a + (Math.PI + Math.PI / 10)) * 15 + ship.y);
    context.lineTo(Math.cos(ship.a) * 10 + ship.x, Math.sin(ship.a) * 10 + ship.y);

    context.fillStyle = '#8ED6FF';
    context.fill();
    context.lineWidth = 1;
    context.strokeStyle = 'black';
    context.stroke();


    context.moveTo(ship.x, ship.y);
    for (var i = 0; i < 7; i++) {
        var a1 = (Math.PI * 2) * i / 6;
        context.lineTo(Math.cos(ship.a + a1) * 7.5 + ship.x, Math.sin(ship.a + a1) * 7.5 + ship.y);
    }
    context.fillStyle = '#DDDDDD';
    context.fill();
    context.lineWidth = 1;
    context.strokeStyle = 'black';
    context.stroke();
}

function drawEnemyShip1(ship, context, color) {
    if (ship.model !== 2) {

        if (ship.isBoss) {
            drawBoss(ship, context);
        }
        else {

            context.beginPath();
            context.moveTo(ship.x, ship.y);

            for (var i = 0; i < 7; i++) {
                var a1 = (Math.PI * 2) * i / 6;
                context.lineTo(Math.cos(ship.a + a1) * 10 + ship.x, Math.sin(ship.a + a1) * 10 + ship.y);
            }

            context.fillStyle = color;
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = 'black';
            context.stroke();
        }
    }
    else {
        if (ship.isBoss) {
            drawBoss(ship, context);
        }
        else {
            drawEnemyShipFast(ship, context, color)
        }
    }
}

function drawEnemyShipFast(ship, context, color) {


    context.beginPath();
    context.moveTo(Math.cos(ship.a) * 10 + ship.x, Math.sin(ship.a) * 10 + ship.y);
    context.lineTo(Math.cos(ship.a - (Math.PI + Math.PI / 10)) * 15 + ship.x, Math.sin(ship.a - (Math.PI + Math.PI / 10)) * 15 + ship.y);
    context.lineTo(Math.cos(ship.a + (Math.PI + Math.PI / 10)) * 15 + ship.x, Math.sin(ship.a + (Math.PI + Math.PI / 10)) * 15 + ship.y);
    context.lineTo(Math.cos(ship.a) * 10 + ship.x, Math.sin(ship.a) * 10 + ship.y);

    context.fillStyle = "#447766";
    context.fill();
    context.lineWidth = 1;
    context.strokeStyle = 'black';
    context.stroke();

    context.moveTo(Math.cos(ship.a) * 10 + ship.x, Math.sin(ship.a) * 10 + ship.y);
    context.lineTo(Math.cos(ship.a - (Math.PI + Math.PI / 10) + Math.PI / 2) * 15 + ship.x, Math.sin(ship.a - (Math.PI + Math.PI / 10) + Math.PI / 2) * 15 + ship.y);
    context.lineTo(Math.cos(ship.a + (Math.PI + Math.PI / 10) - Math.PI / 2) * 15 + ship.x, Math.sin(ship.a + (Math.PI + Math.PI / 10) - Math.PI / 2) * 15 + ship.y);
    context.lineTo(Math.cos(ship.a) * 10 + ship.x, Math.sin(ship.a) * 10 + ship.y);

    context.fillStyle = color;
    context.fill();
    context.lineWidth = 1;
    context.strokeStyle = 'black';
    context.stroke();
}

function drawBoss(ship, context) {
    // main hull
    context.beginPath();
    context.moveTo(ship.x, ship.y);

    for (var i = 0; i < 7; i++) {
        var a1 = (Math.PI * 2) * i / 6;
        context.lineTo(Math.cos(ship.a + a1) * 15 + ship.x, Math.sin(ship.a + a1) * 15 + ship.y);
    }

    context.fillStyle = "#559922";
    context.fill();
    context.lineWidth = 1;
    context.strokeStyle = 'black';
    context.stroke();

    // engines

    for (var ei = 0; ei < 4; ei++) {
        var engine = ship.engines[ei];
        if (engine != null) {

            if (engine.exploid === null) {

                var eA = ship.a + Math.PI * 2 / 4 * ei + Math.PI / 4;
                var eX = Math.cos(eA) * 15 + ship.x;
                var eY = Math.sin(eA) * 15 + ship.y;

                engine.x = eX;
                engine.y = eY;

                context.beginPath();
                context.moveTo(eX, eY);
                for (var i = 0; i < 9; i++) {
                    var a1 = (Math.PI * 2) * i / 8;
                    context.lineTo(Math.cos(ship.a + a1) * 7 + eX, Math.sin(ship.a + a1) * 7 + eY);
                }

                context.fillStyle = "#559999";
                context.fill();
                context.lineWidth = 1;
                context.strokeStyle = 'black';
                context.stroke();
            }
            else {
                engine.exploid++;
                if (engine.exploid < 100) {

                    context.beginPath();
                    context.arc(engine.x, ship.y, engine.exploid / 40, 0, 2 * Math.PI, false);
                    context.arc(engine.x + 3, ship.y + 2, engine.exploid / 20, 0, 2 * Math.PI, false);
                    context.arc(engine.x - 10, ship.y - 2, engine.exploid / 25, 0, 2 * Math.PI, false);
                    context.fillStyle = 'red';
                    context.fill();
                    context.lineWidth = 1;
                    context.strokeStyle = '#003300';
                    context.stroke();
                }
                else {
                    ship.engines[ei] = null;
                }
            }
        }
    }
}

function drawBullets(context) {

    for (var i = 0; i < bullets.length; i++) {
        var bullet = bullets[i];

        if (bullet.isBoss) {
            context.beginPath();
            context.moveTo(Math.cos(bullet.a) * 10 + bullet.x, Math.sin(bullet.a) * 10 + bullet.y);
            context.lineTo(Math.cos(bullet.a - (Math.PI + Math.PI / 10)) * 10 + bullet.x, Math.sin(bullet.a - (Math.PI + Math.PI / 10)) * 10 + bullet.y);
            context.lineTo(Math.cos(bullet.a + (Math.PI + Math.PI / 10)) * 10 + bullet.x, Math.sin(bullet.a + (Math.PI + Math.PI / 10)) * 10 + bullet.y);
            context.lineTo(Math.cos(bullet.a) * 10 + bullet.x, Math.sin(bullet.a) * 10 + bullet.y);

            context.fillStyle = 'orange';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = 'rgba(0,0,0,0)';
            context.stroke();
        }
        else {
            context.beginPath();
            context.arc(bullet.x, bullet.y, 4, 0, 2 * Math.PI, false);
            context.fillStyle = 'yellow';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = '#559966';
            context.stroke();
        }
        
    }
}

function drawRocks(context) {

    for (var i = 0; i < rocks.length; i++) {
        var rock = rocks[i];

        context.beginPath();
        context.arc(rock.x, rock.y, 7, 0, 2 * Math.PI, false);
        context.fillStyle = '#555555';
        context.fill();
        context.lineWidth = 1;
        context.strokeStyle = '#eeaaaa';
        context.stroke();

        var a = (rock.x + rock.y) / 10;
        for (var j = 1; j < 5; j++) {
            context.beginPath();
            context.arc(rock.x + (a * j * 131 % 5), rock.y + (a * j * 177 % 5), 4, 0, 2 * Math.PI, false);
            context.fillStyle = '#555555';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = '#eeaaaa';
            context.stroke();
        }
    }
}


function drawStars(context) {
    for (var i = 0; i < stars.length; i++) {
        var star = stars[i];
        context.beginPath();
        context.arc(star.x + ship.x / 10, star.y + ship.x / 10, 1, 0, 2 * Math.PI, false);
        context.fillStyle = '#464';
        context.fill();
        context.lineWidth = 1;
        context.strokeStyle = '#464';
        context.stroke();
    }
}

function drawTitle(ctx)
{
    ctx.save();
    ctx.beginPath();

    ctx.translate(225, 200);
    ctx.translate(0, 0);
    ctx.scale(1.5, 1.5)
    ctx.translate(0, 0);
    ctx.strokeStyle = 'rgba(255,255,255,1)';
    ctx.lineCap = 'butt';
    ctx.lineJoin = 'miter';
    ctx.miterLimit = 4;
    ctx.save();
    ctx.restore();
    ctx.save();
    ctx.fillStyle = "#000";
    ctx.strokeStyle = "rgba(255, 1, 1, 1)";
    ctx.lineWidth = 50;
    ctx.translate(0, 160);
    ctx.scale(0.1, -0.1);
    ctx.save();

    ctx.moveTo(1454, 1383);
    ctx.bezierCurveTo(1474, 1351, 1490, 1321, 1490, 1315);
    ctx.bezierCurveTo(1490, 1309, 1499, 1299, 1510, 1292);
    ctx.bezierCurveTo(1529, 1280, 1561, 1227, 1574, 1183);
    ctx.bezierCurveTo(1580, 1163, 1575, 1157, 1528, 1135);
    ctx.lineTo(1475, 1110);
    ctx.lineTo(1531, 1113);
    ctx.bezierCurveTo(1588, 1115, 1620, 1101, 1620, 1074);
    ctx.bezierCurveTo(1620, 1061, 1601, 1054, 1550, 1048);
    ctx.bezierCurveTo(1530, 1045, 1536, 1041, 1580, 1025);
    ctx.bezierCurveTo(1616, 1012, 1639, 996, 1649, 978);
    ctx.bezierCurveTo(1673, 935, 1655, 929, 1570, 951);
    ctx.bezierCurveTo(1427, 989, 1400, 967, 1400, 812);
    ctx.bezierCurveTo(1400, 700, 1392, 674, 1342, 627);
    ctx.lineTo(1313, 599);
    ctx.lineTo(1300, 629);
    ctx.bezierCurveTo(1280, 679, 1261, 668, 1258, 604);
    ctx.bezierCurveTo(1255, 556, 1251, 546, 1227, 532);
    ctx.bezierCurveTo(1202, 517, 1197, 517, 1172, 530);
    ctx.bezierCurveTo(1148, 544, 1145, 552, 1142, 603);
    ctx.bezierCurveTo(1139, 668, 1116, 682, 1097, 630);
    ctx.bezierCurveTo(1091, 614, 1082, 600, 1079, 600);
    ctx.bezierCurveTo(1064, 600, 1009, 676, 1000, 710);
    ctx.bezierCurveTo(994, 729, 990, 777, 990, 816);
    ctx.bezierCurveTo(990, 906, 976, 948, 943, 956);
    ctx.bezierCurveTo(919, 962, 842, 957, 772, 944);
    ctx.bezierCurveTo(741, 938, 739, 939, 742, 960);
    ctx.bezierCurveTo(746, 991, 786, 1019, 840, 1028);
    ctx.lineTo(885, 1036);
    ctx.lineTo(837, 1044);
    ctx.bezierCurveTo(785, 1052, 772, 1067, 790, 1099);
    ctx.bezierCurveTo(798, 1115, 811, 1120, 848, 1121);
    ctx.lineTo(895, 1122);
    ctx.lineTo(858, 1137);
    ctx.bezierCurveTo(837, 1146, 820, 1158, 820, 1165);
    ctx.bezierCurveTo(820, 1180, 869, 1248, 898, 1274);
    ctx.bezierCurveTo(910, 1284, 934, 1324, 951, 1361);
    ctx.bezierCurveTo(969, 1399, 985, 1430, 987, 1430);
    ctx.bezierCurveTo(989, 1430, 1009, 1418, 1031, 1403);
    ctx.bezierCurveTo(1067, 1379, 1074, 1378, 1093, 1390);
    ctx.bezierCurveTo(1171, 1439, 1222, 1443, 1295, 1405);
    ctx.lineTo(1344, 1381);
    ctx.lineTo(1370, 1403);
    ctx.bezierCurveTo(1384, 1415, 1396, 1428, 1398, 1433);
    ctx.bezierCurveTo(1406, 1450, 1420, 1437, 1454, 1383);
    ctx.closePath();
    ctx.moveTo(722, 618);
    ctx.bezierCurveTo(735, 595, 759, 566, 777, 554);
    ctx.bezierCurveTo(843, 509, 1155, 418, 1504, 340);
    ctx.bezierCurveTo(1623, 314, 1655, 310, 1724, 316);
    ctx.bezierCurveTo(1817, 323, 1834, 314, 1828, 258);
    ctx.bezierCurveTo(1825, 229, 1822, 225, 1797, 225);
    ctx.bezierCurveTo(1773, 226, 1770, 223, 1774, 205);
    ctx.bezierCurveTo(1778, 194, 1783, 175, 1786, 163);
    ctx.bezierCurveTo(1790, 147, 1784, 133, 1766, 115);
    ctx.bezierCurveTo(1734, 83, 1709, 93, 1684, 146);
    ctx.bezierCurveTo(1658, 200, 1617, 224, 1465, 273);
    ctx.bezierCurveTo(1245, 345, 819, 450, 749, 450);
    ctx.bezierCurveTo(738, 450, 714, 439, 696, 425);
    ctx.bezierCurveTo(655, 394, 638, 394, 604, 423);
    ctx.bezierCurveTo(578, 446, 578, 447, 594, 477);
    ctx.bezierCurveTo(603, 495, 619, 515, 629, 522);
    ctx.bezierCurveTo(643, 532, 646, 540, 639, 550);
    ctx.bezierCurveTo(616, 588, 640, 660, 676, 660);
    ctx.bezierCurveTo(692, 660, 705, 648, 722, 618);
    ctx.closePath();
    ctx.moveTo(1735, 617);
    ctx.bezierCurveTo(1749, 606, 1752, 595, 1747, 560);
    ctx.bezierCurveTo(1742, 523, 1745, 514, 1765, 498);
    ctx.bezierCurveTo(1798, 472, 1806, 443, 1784, 419);
    ctx.bezierCurveTo(1762, 395, 1753, 395, 1696, 421);
    ctx.bezierCurveTo(1653, 440, 1642, 441, 1557, 430);
    ctx.bezierCurveTo(1506, 424, 1439, 412, 1407, 404);
    ctx.bezierCurveTo(1351, 390, 1293, 392, 1260, 411);
    ctx.bezierCurveTo(1248, 418, 1248, 419, 1263, 420);
    ctx.bezierCurveTo(1291, 420, 1528, 489, 1564, 507);
    ctx.bezierCurveTo(1606, 528, 1640, 560, 1640, 578);
    ctx.bezierCurveTo(1640, 620, 1698, 644, 1735, 617);
    ctx.closePath();
    ctx.moveTo(1134, 357);
    ctx.lineTo(1182, 344);
    ctx.lineTo(1029, 301);
    ctx.bezierCurveTo(775, 229, 756, 220, 708, 131);
    ctx.bezierCurveTo(674, 69, 599, 110, 628, 175);
    ctx.bezierCurveTo(644, 209, 643, 210, 620, 210);
    ctx.bezierCurveTo(592, 210, 560, 245, 560, 275);
    ctx.bezierCurveTo(560, 315, 596, 326, 686, 313);
    ctx.bezierCurveTo(765, 302, 836, 310, 990, 349);
    ctx.bezierCurveTo(1084, 372, 1076, 372, 1134, 357);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
    ctx.restore();
    ctx.restore();
    ctx.restore();
}

function animate(ship, canvas, context, startTime) {
    // update
    var time = (new Date()).getTime() - startTime;

    if (gameStarted) {

        // move
        if (isMovingLeft && !isMovingRight) {
            ship.a -= 0.03;
        }

        if (isMovingRight && !isMovingLeft) {
            ship.a += 0.03;
        }

        if (ship.exploid === null) {
            var newX = Math.cos(ship.a) * ship.s + ship.x;
            var newY = Math.sin(ship.a) * ship.s + ship.y;

            ship.x = newX;
            ship.y = newY;

            if (ship.x < 0 || ship.y < 0 || ship.x > canvas.width || ship.y > canvas.height) {
                ship.exploid = 0;
                shipExploidHandler();
            }

            var crush = false;
            for (var i = 0; i < rocks.length; i++) {
                if (Math.abs(rocks[i].x - ship.x) < 10 && Math.abs(rocks[i].y - ship.y) < 10) {
                    ship.exploid = 0;
                    shipExploidHandler();
                }
            }
        }

        for (var i = 0; i < enemyShips.length; i++) {
            var eship = enemyShips[i];
            if (eship.exploid === null) {
                var dx = ship.x - eship.x,
                  dy = ship.y - eship.y,
                  len = Math.sqrt(dx * dx + dy * dy);
                dx /= len ? len : 1.0; dy /= len ? len : 1.0;
                // get current direction
                var dirx = Math.cos(eship.a),
                    diry = Math.sin(eship.a);
                // ease the current direction to the target direction
                dirx += (dx - dirx) * eship.easing;
                diry += (dy - diry) * eship.easing;

                eship.a = Math.atan2(diry, dirx);
                eship.targetAngle = Math.atan2(dy, dx);


                var newX = Math.cos(eship.a) * eship.s + eship.x;
                var newY = Math.sin(eship.a) * eship.s + eship.y;

                eship.x = newX;
                eship.y = newY;

                eship.currentReload += Math.random();
                if (eship.currentReload >= eship.reload) {
                    eship.currentReload = 0;

                    if (eship.isBoss) {
                        var aliveEngines = getAliveEngines(eship);
                        var randomEngineIndex = Math.floor(Math.random() * aliveEngines.length + 1);

                        var x = eship.x;
                        var y = eship.y;
                        if (randomEngineIndex < aliveEngines.length) {
                            x = aliveEngines[randomEngineIndex].x;
                            y = aliveEngines[randomEngineIndex].y;
                        }

                        var bullet = createBullet(x, y, eship.a, 1, 2 + Math.random(), 200);
                        bullet.isBoss = true;
                        bullets.push(bullet);
                    }
                    else {

                        var bullet = createBullet(eship.x, eship.y, eship.a, 1, 2 + Math.random(), 200);
                        bullets.push(bullet);
                    }
                }

                if (getDistance(eship, ship) < 10 && ship.exploid === null) {
                    ship.exploid = 0;
                    shipExploidHandler();

                    if (!eship.isBoss) {
                        eship.exploid = 0;
                        botExploidHandler(eship);
                    }
                }

                if (eship.mazed > 0) {
                    eship.mazed--;
                }

                if (!eship.isBoss) {
                    for (var j = 0; j < rocks.length; j++) {
                        if (Math.abs(rocks[j].x - eship.x) < 10 && Math.abs(rocks[j].y - eship.y) < 10 && eship.mazed <= 0) {
                            eship.a += Math.PI;
                            eship.targetAngle += Math.PI;
                            eship.mazed = 10;
                            continue;
                        }
                    }
                }
            }
        }

        for (var i = 0; i < bullets.length; i++) {
            var bullet = bullets[i];

            var newX = Math.cos(bullet.a) * bullet.s + bullet.x;
            var newY = Math.sin(bullet.a) * bullet.s + bullet.y;
            bullet.x = newX;
            bullet.y = newY;

            if (bullet.team === 1 && getDistance(bullet, ship) < 7.5 && ship.exploid === null) {
                ship.exploid = 0;
                bullet.exploid = 0;
                shipExploidHandler();
            }

            if (bullet.team === 0) {
                for (var j = 0; j < enemyShips.length; j++) {
                    var eship = enemyShips[j];
                    if (eship.exploid !== null) {
                        continue;
                    }

                    if (!eship.isBoss) {
                        if (getDistance(bullet, eship) < 10) {
                            eship.exploid = 0;
                            bullet.exploid = 0;

                            botExploidHandler(eship);
                        }
                    }
                    else {
                        var aliveEngines = getAliveEngines(eship);
                        var engineHit = false;
                        if (aliveEngines.length > 0) {

                            for (var ei = 0; ei < aliveEngines.length; ei++) {
                                if (getDistance(aliveEngines[ei], bullet) < 5) {
                                    aliveEngines[ei].exploid = 0;
                                    bullet.exploid = 0;
                                    eship.currentReload = 0;
                                    eship.reload -= 15;
                                    botDestroedScope += 75;

                                    if (aliveEngines.length > 1) {
                                        eship.easing -= 0.015;
                                        if (eship.easing <= 0.015) {
                                            eship.easing = 0.015;
                                        }
                                    }
                                    else {
                                        eship.easing = 0.05;
                                    }
                                    eship.s -= 0.01;
                                    if (eship.s <= 0) {
                                        eship.s = 0.01;
                                    }
                                    engineHit = true;
                                    break;
                                }
                            }


                        }

                        if (getDistance(eship, bullet) < 15) {
                            if (!engineHit) {
                                bullet.exploid = 0;
                                if (aliveEngines.length === 0) {
                                    eship.exploid = 0;
                                    botExploidHandler(eship);
                                }
                            }
                        }
                    }


                }
            }

            if (bullet.x < 0 || bullet.y < 0 || bullet.x > canvas.width || bullet.y > canvas.height) {
                bullet.exploid = 0;
            }

            if (bullet.lifetime <= 0) {
                bullet.exploid = 0;
            }
            else {
                bullet.lifetime--;
            }
        }

        removeExploitedBullets();
        removeExploitedShips();
    }

    // clear
    context.clearRect(0, 0, canvas.width, canvas.height);

    context.beginPath();
    context.rect(0, 0, canvas.width, canvas.height);
    context.fillStyle = 'black';
    context.fill();
    context.lineWidth = 7;
    context.strokeStyle = 'gray';
    context.stroke();

    drawStars(context);
    drawShip(ship, context);
    drawBullets(context);
    drawRocks(context);
    for (var i = 0; i < enemyShips.length; i++) {
        var eship = enemyShips[i];
        drawShip(eship, context);
    }

    if (gameStarted) {
        var gametimeSpan = document.getElementById("gametime");
        gametimeSpan.innerHTML = (milliseconds / 10).toFixed(1) + "s";
    }

    if (!gameStarted)
    {
        drawTitle(context);
    }

    // request new frame
    requestAnimFrame(function () {
        animate(ship, canvas, context, startTime);
    });
}

var height = 600//document.body.clientHeight;
var width = 800//document.body.clientWidth;

var mainCanvas = document.getElementById("main-canvas");
mainCanvas.width = width;
mainCanvas.height = height;
var drawingContext = mainCanvas.getContext("2d");

var ecolors = ["#8E8EFF", "#8EFF8F", "#8E4444", "#00008E"];
// main screen
stars = [];
for (var i = 0; i < 100; i++) {
    stars.push({ x: Math.random() * width, y: Math.random() * height });
}

rocks = [];
for (var i = 0; i < 25; i++) {
    var x = Math.random() * (width - 20) + 10;
    var y = Math.random() * (height - 20) + 10;

    if (x > 20 && y > 20) {
        rocks.push({ x: x, y: y });
    }
}

var startTime = (new Date()).getTime();
animate(ship, mainCanvas, drawingContext, startTime);

var timerHandler;

document.onkeydown = function (e) {
    var charCode = (typeof e.which == "number") ? e.which : e.keyCode
    if (charCode == 65) {
        isMovingRight = false;
        isMovingLeft = true;
    }
    else if (charCode == 68) {
        isMovingLeft = false;
        isMovingRight = true;
    }
    else if (charCode == 32) {

        if (gameStarted && !shipExploided) {

            if (ship.exploid > 0)
                return;

            var allow = true;
            for (var i = 0; i < bullets.length; i++) {
                var bullet = bullets[i];
                if (bullet.team === 0) {
                    allow = false;
                    break;
                }
            }

            if (allow) {
                bullets.push(
                    createBullet(ship.x,
                    ship.y,
                    ship.a,
                    0,
                    5,
                    200));
                shotCount++;
            }
        }
        else {
            startGame();
        }
    }
};

document.onkeyup = function (e) {
    var charCode = (typeof e.which == "number") ? e.which : e.keyCode
    if (charCode == 65) {
        isMovingRight = false;
        isMovingLeft = false;
    }
    else if (charCode == 68) {
        isMovingLeft = false;
        isMovingRight = false;
    }
};

function getDistance(a, b)
{
    return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

function getAliveEngines(eship) {
    var aliveEngines = [];
    for (var i = 0; i < eship.engines.length; i++) {
        var engine = eship.engines[i];
        if (!engine) {
            continue;
        }

        if (engine.exploid !== null) {
            continue;
        }

        aliveEngines.push(engine);
    }

    return aliveEngines;
}

function removeExploitedBullets() {
    var i = 0;
    while (i < bullets.length) {
        if (bullets[i].exploid === 0) {
            bullets.splice(i, 1);
        }

        i++;
    }
}

function removeExploitedShips() {
    var i = 0;
    while (i < enemyShips.length) {
        if (enemyShips[i].exploid !== null && enemyShips[i].exploid > 200) {
            enemyShips.splice(i, 1);
        }

        i++;
    }
}

function startGame() {

    ship.x = 10;
    ship.y = 10;
    ship.a = 0;
    ship.exploid = null;
    shipExploided = false;

    botDestroedScope = 0;
    milliseconds = 0;
    enemyShips = [];
    firstBlood = false;
    minionsDead = false;
    bullets = [];

    timerHandler = setInterval(function () {
        milliseconds++;
    }, 100);

    enemyShips.push(createEShip(width / 2, height / 2, 0));

    stars = [];
    for (var i = 0; i < 100; i++) {
        stars.push({ x: Math.random() * width, y: Math.random() * height });
    }

    rocks = [];
    for (var i = 0; i < 25; i++) {
        var x = Math.random() * (width - 20) + 10;
        var y = Math.random() * (height - 20) + 10;

        if (x > 20 && y > 20) {
            rocks.push({ x: x, y: y });
        }
    }

    gameStarted = true;
    var commandMessageSpan = document.getElementById("command-message");
    commandMessageSpan.innerText = "";

    var resultMessageSpan = document.getElementById("result-message");
    resultMessageSpan.innerText = "";

    var scoreMessageSpan = document.getElementById("score-message");
    scoreMessageSpan.innerText = "";
    var logoMessageSpan = document.getElementById("logo");
    logoMessageSpan.style.display = "none";

    if (bossSpawnTimer)
    {
        clearTimeout(bossSpawnTimer);
    }

    if (fastSpawnTimer) {
        clearTimeout(fastSpawnTimer);
    }

    if (guardSpawnTimer) {
        clearTimeout(guardSpawnTimer);
    }

    if (resultShowTime)
    {
        clearTimeout(resultShowTime);
    }

    if (restartCommandTimer)
    {
        clearTimeout(restartCommandTimer);
    }
}

var shipExploided = false;
var resultShowTime;
var restartCommandTimer;
function shipExploidHandler() {
    var baseScope = 100;

    var totalScope = baseScope - Math.round(milliseconds/10) - shotCount + botDestroedScope;

    clearTimeout(timerHandler);

    resultShowTime = setTimeout(function () {
        var resultMessageSpan = document.getElementById("result-message");
        resultMessageSpan.innerText = "YOU ARE DEAD";

        var scoreMessageSpan = document.getElementById("score-message");
        scoreMessageSpan.innerText = "Score: " + totalScope;

        shipExploided = true;

        restartCommandTimer = setTimeout(function () {
            var commandMessageSpan = document.getElementById("command-message");
            commandMessageSpan.innerText = "PRESS [SPACE] TO RESTART";
        }, 1000);
    }, 2000);
}

function botExploidHandler(eship) {

    botDestroedScope += (eship.model + 1) * 50;

    if (eship.isBoss)
    {
        resultShowTime = setTimeout(function () {
            var resultMessageSpan = document.getElementById("result-message");
            resultMessageSpan.innerText = "YOU ARE WINNER";

            var scoreMessageSpan = document.getElementById("score-message");
            scoreMessageSpan.innerText = "Score: " + totalScope;

            clearTimeout(timerHandler);

            restartCommandTimer = setTimeout(function () {
                var commandMessageSpan = document.getElementById("command-message");
                commandMessageSpan.innerText = "PRESS [SPACE] TO RESTART";
            }, 1000);

        }, 2000);

        return;
    }

    if (ship.exploid !== null)
        return;

    if (!firstBlood) {
        firstBlood = true;
        startShowingFirstBloodText();
        startSpawn();
    } else {

        var notExploitedBots = false;
        for (var i = 0; i < enemyShips.length; i++) {
            if (enemyShips[i].exploid !== 0) {
                notExploitedBots = true;
            }
        }

        if (!minionsDead && !notExploitedBots) {
            minionsDead = true;
            startShowingBossText();
            startSpawnBoss();
        }
    }
}

function startShowingFirstBloodText() {
    var infoMessageSpan = document.getElementById("info-message");
    infoMessageSpan.innerText = "It was easy. Ok, lets try something more...";
    setTimeout(function () {
        infoMessageSpan.innerText = "";
    }, 8000);
}

function startShowingBossText() {
    var infoMessageSpan = document.getElementById("info-message");
    infoMessageSpan.innerText = "All guardians are dead. And now prepare to die.";
    setTimeout(function () {
        infoMessageSpan.innerText = "";
    }, 6000);
}


var guardSpawnTimer;
function startSpawn() {
    guardSpawnTimer = setTimeout(function () {
        for (var i = 0; i < 5; i++) {
            if (i % 2 === 0) {
                enemyShips.push(createEShip(width, Math.random() * height, 1));
            }
            else {
                enemyShips.push(createEShip(Math.random() * width, height, 1));
            }
        }

        startSpawnFast();
    }, 8000);
}

var fastSpawnTimer;

function startSpawnFast() {

    fastSpawnTimer = setTimeout(function () {
        for (var i = 0; i < 3; i++) {
            if (i % 2 === 0) {
                enemyShips.push(createEShip(width, Math.random() * height, 2));
            }
            else {
                enemyShips.push(createEShip(Math.random() * width, height, 2));
            }
        }
    }, 20000);
}

var bossSpawnTimer;

function startSpawnBoss() {

    bossSpawnTimer = setTimeout(function () {
        var bossShip = createEShip(width, Math.random() * height, 3);
        bossShip.isBoss = true;
        bossShip.reload = 60;
        bossShip.easing = 0.05;
        enemyShips.push(bossShip);
    }, 8000);
}

function createEShip(x, y, model) {
    var speed = [0.3, 0.3, 0.8, 0.5];
    var easing = [0.1, 0.1, 0.072, 0.1];

    var factSpeed = speed[model];
    if (model === 2)
    {
        factSpeed += Math.random() * 0.5;
    }

    var ship = {
        x: x,
        y: y,
        a: 0,
        s: factSpeed,
        exploid: null,
        reload: 100,
        currentReload: 0,
        model: model,

        targetAngle: 0,
        easing: easing[model],

        mazed: 0,

        engines: []
    };

    for (var i = 0; i < 4; i++)
    {
        ship.engines[i] = {
            x: 0,
            y: 0,
            exploid: null
        };
    }

    return ship;
}

function createBullet(x, y, a, team, speed, lifetime) {
    return {
        x: x,
        y: y,
        a: a,
        s: speed,
        team: team,
        lifetime: lifetime
    }
}