var lasers = [];
var enemies = [];
var explosions = [];
var hero;
var gameID;
var gameOver;
var gameWon;
var time = [];


var winImg = document.createElement('img');
    winImg.src = './img/win.png';
var gameOverImg = document.createElement('img');
    gameOverImg.src = './img/gameover.jpg';
var bgImg = document.createElement('img');
var bgPosition = 0;


function game() {

    gameOver = 0;
    gameWon = 0;
    enemies.length = 0;
    explosions.length = 0;
    lasers.length = 0;

    for(var i=0; i<time.length; i++) {
        clearTimeout(time[i]);
    }

    canvas = document.getElementById("myCanvas");

    if (canvas.getContext)
    {
      ctx = canvas.getContext("2d");

      makeGameBackground();
      hero = new Hero();
    }

    lasers.enableLaser = true;
    makeEnemies();

    gameID = setInterval(gameLoop, 10);
    gameSoundID = setInterval(gameSound, 1000);
    addEventListener('keydown', downKey);
    addEventListener('keyup', upKey);
}


var gameLoop = function() {
    backgroundDraw();

    if(hero.x < 0) {
    	hero.x = 0;
    }
    if(hero.x > ctx.canvas.width - hero.shipSize) {
    	hero.x = ctx.canvas.width - hero.shipSize;
    }
	if(hero.y > ctx.canvas.height - hero.shipSize) {
    	hero.y = ctx.canvas.height - hero.shipSize;
  	}
	if(hero.y < 0) {
    	hero.y = 0;
  	}

    hero.Draw();
    hero.Move();

    // proofs if bounding box from Enemy is in bounding box from Hero
    for (var index = 0; index<enemies.length; index++) {
    var currentEnemy = enemies[index];
    if( (hero.y >= currentEnemy.y && hero.y <= (currentEnemy.y + currentEnemy.ufoHeight)) || 
                ((hero.y + hero.shipSize) >= currentEnemy.y && (hero.y + hero.shipSize) <= (currentEnemy.y + currentEnemy.ufoHeight)) ) {
    	if( (hero.x >= currentEnemy.x && hero.x <= (currentEnemy.x + currentEnemy.ufoWidth)) || 
    	    ((hero.x + hero.shipSize) >= currentEnemy.x && (hero.x + hero.shipSize) <= (currentEnemy.x + currentEnemy.ufoWidth)) ) {    		

    	   		gameOverExplosion = new Explosion(hero.canvas, hero.shipSize, hero.shipSize, hero.x, hero.y);
                var lastBoom = new Enemy();
                lastBoom.explosionSound.play();
    	   		gameOver = 1;
    	   		break;
    		}
    	}
    }

    // proofs if bounding box from Laser is in bounding box from Enemy
    for (var indexLaser = 0; indexLaser<lasers.length; indexLaser++) {
    var currentLaser = lasers[indexLaser];
    	for (var indexEnemy = 0; indexEnemy<enemies.length; indexEnemy++) {
    	var currentEnemy = enemies[indexEnemy];
    		if( (currentLaser.x >= currentEnemy.x && currentLaser.x <= (currentEnemy.x + currentEnemy.ufoWidth)) || 
    	        ((currentLaser.x + currentLaser.laserWidth) >= currentEnemy.x && (currentLaser.x + currentLaser.laserWidth) <= (currentEnemy.x + currentEnemy.ufoWidth)) ) {
	    		if( (currentLaser.y >= currentEnemy.y && currentLaser.y <= (currentEnemy.y + currentEnemy.ufoHeight)) || 
	    	   	    ((currentLaser.y + currentLaser.laserHeight) >= currentEnemy.y && (currentLaser.y + currentLaser.laserHeight) <= (currentEnemy.y + currentEnemy.ufoHeight)) ) {

	    			currentEnemy.life--;
	    			lasers.splice(indexLaser,1);
	    			indexLaser--;

					if(currentEnemy.life == 0) {
                        currentEnemy.explosionSound.play();
						explosions.push(new Explosion(currentEnemy.canvas, currentEnemy.ufoWidth, currentEnemy.ufoHeight, currentEnemy.x, currentEnemy.y));						
						enemies.splice(indexEnemy,1);
						indexEnemy--;
					}
					break;
				}
			}
    	}

    	if(currentLaser.x > ctx.canvas.width) {
			lasers.splice(indexLaser,1);
			indexLaser--;
		}	
    }


    for (var indexLaser = 0; indexLaser<lasers.length; indexLaser++) {
    	var currentLaser = lasers[indexLaser];
    	currentLaser.Draw();
        currentLaser.Move();
    }

    // proofs if bounding box from Enemy is at the edge of the canvas
    for (var index = 0; index<enemies.length; index++) {
    	var enemy = enemies[index];
    	enemy.Draw();
    	if(enemy.x < 0) {
    		enemy.movesRight = true;
    		enemy.movesLeft = false;
    	}
    	else if(enemy.x > ctx.canvas.width - enemy.ufoWidth){
    		enemy.movesLeft = true;
    		enemy.movesRight = false;
    	}

    	if(enemy.y < 0) {
    		enemy.movesDown = true;
    		enemy.movesUp = false;
    	}
    	else if(enemy.y + enemy.ufoHeight > ctx.canvas.height) {
    		enemy.movesDown = false;
    		enemy.movesUp = true;
    	}

    	enemy.Move();
    }

    for (var index = 0; index<explosions.length; index++){
    	var currentExplosion = explosions[index];
    	currentExplosion.Draw()
    	if(currentExplosion.counter == 0) {
    		explosions.splice(index,1);
    		index--;
    	}
    }

    if(gameOver == 1) {
    	gameOverExplosion.Draw();
    	clearInterval(gameID);
		var out = function() {
			ctx.drawImage(gameOverImg, 0, 0, ctx.canvas.width, ctx.canvas.height);
            drawBackButton();
            buttonFlag = 3;
            $('#backButton').attr('hidden',false);
            $('#sound')[0].currentTime = 240;
            clearInterval(gameSoundID);
            gameOverSoundID = setInterval(gameOverSound,1000);
            flag = true;
            removeEventListener('keydown', downKey);
            removeEventListener('keyup', upKey);
            addEventListener('keydown', downKeyMenu);
		}
		setTimeout(out,1000);
    }

    if(gameWon == 1) {
    	if(enemies.length == 0) {
    		clearInterval(gameID);
			var out = function() {
				ctx.drawImage(winImg, 0, 0, ctx.canvas.width, ctx.canvas.height);
                drawBackButton();
                buttonFlag = 3;
                $('#backButton').attr('hidden',false);
                $('#sound')[0].currentTime = 70;
                clearInterval(gameSoundID);
                winSoundID = setInterval(winSound,1000);
                flag = true;
                removeEventListener('keydown', downKey);
                removeEventListener('keyup', upKey);
                addEventListener('keydown', downKeyMenu);
			}
			setTimeout(out,1000);            
    	}
    }
}


var makeEnemies = function() {
	time[0] = setTimeout(wave1,2000);
	time[1] = setTimeout(wave2,6000);
	time[2] = setTimeout(wave3,12000);
	time[3] = setTimeout(wave4,20000)
	time[4] = setTimeout(wave5,27000);
	time[5] = setTimeout(wave6,40000);
	time[6] = setTimeout(lastWave,60000);
}

var wave1 = function() {
	pushEnemy();
	setTimeout(pushEnemy,1000);
}

var wave2 = function() {
	pushEnemyMoveUp();
	setTimeout(pushEnemyMoveDown,1000);
}

var wave3 = function() {
    pushEnemyUpperArea();
    setTimeout(pushEnemyLowerArea,1000);
    setTimeout(pushEnemyUpperArea,2000);
    setTimeout(pushEnemyLowerArea,3000);
}

var wave4 = function() {
	pushEnemyMoveDown();
	setTimeout(pushEnemyMoveUp,1000);
	setTimeout(pushEnemyMoveDown,2000);
	setTimeout(pushEnemyMoveUp,3000);
    setTimeout(pushEnemyMoveDown,4000);
    setTimeout(pushEnemyMoveUp,5000);
}

var wave5 = function() {
	pushEnemyUpperArea();
	pushEnemyLowerArea();
	setTimeout(pushEnemyUpperArea,1000);
	setTimeout(pushEnemyLowerArea,1000);
	setTimeout(pushEnemyUpperArea,2000);
	setTimeout(pushEnemyLowerArea,2000);
	setTimeout(pushEnemyUpperArea,3000);
	setTimeout(pushEnemyLowerArea,3000);
	setTimeout(pushEnemyUpperArea,4000);
	setTimeout(pushEnemyLowerArea,4000);
}

var wave6 = function() {
	pushEnemyUpperAreaMoveDown();
	pushEnemyLowerAreaMoveUp();
	setTimeout(pushEnemyUpperAreaMoveDown,1000);
	setTimeout(pushEnemyLowerAreaMoveUp,1000);
	setTimeout(pushEnemyUpperAreaMoveDown,2000);
	setTimeout(pushEnemyLowerAreaMoveUp,2000);
	setTimeout(pushEnemyUpperAreaMoveDown,3000);
	setTimeout(pushEnemyLowerAreaMoveUp,3000);
	setTimeout(pushEnemyUpperAreaMoveDown,4000);
	setTimeout(pushEnemyLowerAreaMoveUp,4000);
	setTimeout(pushEnemyUpperAreaMoveDown,5000);
	setTimeout(pushEnemyLowerAreaMoveUp,5000);
	setTimeout(pushEnemyUpperAreaMoveDown,6000);
	setTimeout(pushEnemyLowerAreaMoveUp,6000);
	setTimeout(pushEnemyUpperAreaMoveDown,6500);
	setTimeout(pushEnemyLowerAreaMoveUp,6500);
	setTimeout(pushEnemyUpperAreaMoveDown,7000);
	setTimeout(pushEnemyLowerAreaMoveUp,7000);
}

var lastWave = function() {
	var boss = new Enemy(undefined,undefined,true);
	boss.ufoWidth = 180;
	boss.ufoHeight = 60;
	boss.life = 20;
	enemies.push(boss);
	gameWon = 1;
}

var pushEnemy = function() {
	enemies.push(new Enemy());
}

var pushEnemyMoveUp = function() {
	enemies.push(new Enemy(undefined,undefined,true));
}

var pushEnemyMoveDown = function() {
	enemies.push(new Enemy(undefined,undefined,false,true));
}

var pushEnemyUpperArea = function() {
	enemies.push(new Enemy(undefined,(ctx.canvas.width/10)));
}

var pushEnemyLowerArea = function() {
	enemies.push(new Enemy(undefined,(ctx.canvas.width/3)));
}

var pushEnemyUpperAreaMoveDown = function() {
	enemies.push(new Enemy(undefined,(ctx.canvas.width/10),false,true));
}

var pushEnemyLowerAreaMoveUp = function() {
	enemies.push(new Enemy(undefined,(ctx.canvas.width/3),true));
}



var makeGameBackground = function() {
    ctx.fillStyle = "black";
    ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.fill();
    for(var i = 0; i < 1000; i++) {
    	var x = Math.floor(Math.random() * ctx.canvas.width);
    	var y = Math.floor(Math.random() * ctx.canvas.height);
    	ctx.fillStyle = "white";
    	ctx.fillRect(x, y, 1, 1);
    }
    var ua = window.navigator.userAgent;
    if (ua.indexOf("Chrome") > 0) {
    	bgImg.src = './img/stars.jpg';
    } else {
    	bgImg.src = canvas.toDataURL();
    }
}

var backgroundDraw = function() {
	ctx.drawImage(bgImg, bgPosition, 0, ctx.canvas.width*4, ctx.canvas.height);
	bgPosition -= 0.2;
	if(bgPosition < -ctx.canvas.width*3) {
		bgPosition = 0;
	}
}



function Hero() {
    this.shipSize = 30;
    this.moveStep = 2;

    this.x = ctx.canvas.width / 20;
    this.y = (ctx.canvas.height - this.shipSize)/2 + 5;

    this.ship = document.createElement('canvas');
    this.ship.width = 30;
    this.ship.height = 30;
    this.canvas = this.ship.getContext('2d');

    this.movesLeft = false;
	this.movesUp = false;
	this.movesRight = false;
	this.movesDown = false;
}

Hero.prototype.Img = document.createElement('img');
Hero.prototype.Img.src = './img/spaceship.png';

Hero.prototype.Draw = function() {
	this.canvas.clearRect(0, 0, this.shipSize, this.shipSize);
    this.canvas.drawImage(this.Img, 0, 0, this.shipSize, this.shipSize);
    ctx.drawImage(this.canvas.canvas, this.x, this.y);
}

Hero.prototype.MoveUp = function() {
   	this.y = this.y - this.moveStep;   	
}

Hero.prototype.MoveDown = function() {
    this.y += this.moveStep;
}

Hero.prototype.MoveLeft = function() {
    this.x -= this.moveStep;
}

Hero.prototype.MoveRight = function() {
    this.x += this.moveStep;
}

Hero.prototype.Move = function() {
	if(this.movesLeft) {
		this.MoveLeft();
	}
	if(this.movesRight) {
		this.MoveRight();
	}
	if(this.movesUp) {
		this.MoveUp();
	}
	if(this.movesDown) {
		this.MoveDown();
	}
}



function Enemy(x, y, up, down, left, right) {
    this.ufoWidth = 60;
    this.ufoHeight = 20;
    this.moveStep = 1;
    this.life = 2;

    this.x = x || (ctx.canvas.width - this.ufoWidth);
    this.y = y || ((ctx.canvas.height - this.ufoHeight)/2);    

    this.ufo = document.createElement('canvas');
    this.canvas = this.ufo.getContext('2d');

    this.explosionSound = document.createElement('audio');
    this.explosionSound.src = './audio/explosion.ogg';

    this.movesLeft = left || true;
	this.movesUp = up || false;
	this.movesRight = right || false;
	this.movesDown = down || false;    
}

Enemy.prototype.Img = document.createElement('img');
Enemy.prototype.Img.src = './img/ufo.png';

Enemy.prototype.Draw = function() {
    this.canvas.drawImage(this.Img, 0, 0, this.ufoWidth, this.ufoHeight);
    ctx.drawImage(this.canvas.canvas, this.x, this.y);
}

Enemy.prototype.MoveLeft = function() {
		this.x -= this.moveStep;
}

Enemy.prototype.MoveRight = function() {
		this.x += this.moveStep;
}

Enemy.prototype.MoveUp = function() {
   	this.y -= this.moveStep;   	
}

Enemy.prototype.MoveDown = function() {
    this.y += this.moveStep;
}

Enemy.prototype.Move = function() {
	if(this.movesLeft) {
	this.MoveLeft();
	}
	if(this.movesRight) {
		this.MoveRight();
	}
	if(this.movesUp) {
		this.MoveUp();
	}
	if(this.movesDown) {
		this.MoveDown();
	}
}



function Explosion(canvas, width, height, x, y) {
	this.counter = 10;

	this.canvas = canvas;
	this.explosionWidth = width;
	this.explosionHeight = height;
	this.x = x;
	this.y = y;	
}

Explosion.prototype.Img = document.createElement('img');
Explosion.prototype.Img.src = './img/explosion.png';

Explosion.prototype.Draw = function() {
	this.counter--;
	this.canvas.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
	this.canvas.drawImage(this.Img, 0, 0, this.explosionWidth, this.explosionHeight);
	ctx.drawImage(this.canvas.canvas, this.x, this.y);
}



function Laser(x,y) {
    this.x = x + hero.shipSize;
    this.y = y + hero.shipSize/2;
    this.laserWidth = 10;
    this.laserHeight = 5;
    this.laserSound = document.createElement('audio');
    this.laserSound.src = './audio/laser.ogg';
}

Laser.prototype.Draw = function() {
    ctx.strokeStyle = "rgb(255, 0, 0)";
    //Linienstärke
    ctx.lineWidth = this.laserHeight;
    //Linienenden abgerundet
    ctx.lineCap = "round";
    //Linienstoss abgerundet
    ctx.lineJoin = "round";
    ctx.beginPath();
    ctx.moveTo(this.x, this.y);
    ctx.lineTo(this.x + this.laserWidth, this.y);
    ctx.closePath();
    ctx.stroke();
}

Laser.prototype.Move = function() {
    this.x += 2;
}

Laser.prototype.enableLaser = false;

var pushLaser = function() {
    var currentLaser = new Laser(hero.x, hero.y);
    currentLaser.laserSound.play();
	lasers.push(currentLaser);
}



function downKey(e) {

    switch (e.keyCode) {

        // Left arrow.
        case 37:
            hero.movesLeft = true;
	        break;

        // Right arrow.
        case 39:
            hero.movesRight = true;            
            break;

        // Down arrow
        case 40:
            hero.movesDown = true;	
          	break;

        // Up arrow 
        case 38:
            hero.movesUp = true;
          	break;

        // Space
        case 32:
        	if(lasers.enableLaser) {
        		pushLaser();
        		lasers.enableLaser = false;
        	}
            break;
    }
}

function upKey(e) {

    switch (e.keyCode) {
    	// Left arrow.
    	case 37:
            hero.movesLeft = false;
            break;

        // Right arrow.
        case 39:
            hero.movesRight = false;
            break;

        // Up arrow 
        case 38:
            hero.movesUp = false;
            break;

        // Down arrow
        case 40:
            hero.movesDown = false;
            break;

        // Space
        case 32:
        	lasers.enableLaser = true;
        	break;
    }
}