if (localStorage.highscore==undefined)
localStorage.highscore="0";
var life=5;
var jsNemo = {
    options : {
        canvas : {
            width : 500,
            height : 400,
            refreshRate : 35,
			img : null
        },
        nemo : {
            width : 30,
            height : 15,
            topSpeed : 5,
            acceleration : 0.35,
            img : null
        },
        physics : {
            terminalVelocity : 06,
            gravity : 0.5,
            friction : 1.0
        },
        walls : {
            separation : 19,
            width : 50,                        
            step : 5,       
            startHeight : 20,
            maxHeight : 120,
            heightIncreaseInterval : 5,
            heightIncreaseStep : 10    
        },
        obstacles : {
            separation : 300,
            width : 20,
            height : 40
        },
        colours : {
            bg : "orange",
            fillTop : "#ddddff",
            fillBot : "#333333",
            fillObs1 : "#444444",
            fillObs2 : "#444444",
            fillObs3 : "#444444",
            light : "black"
        }
    },
    
    gameData : {
        nemo : {
            x : 20,
            y : 10,
            speed : 0,
            rotation : 0
        },
        walls : {
            counter : 0,
            currentHeight : 0,
            currentStep : 0,
            heightIncreaseInterval : 0,
            current : []
        },
        obstacles : {
            counter : 0,
            current : []
        }
    },
    
    scores : {
        current : 0,
        top : 0,
        elements : {
            current : null,
            top : null
        },
        halfStep : 0
    },
    canvas : null,
    container : null,
    canvasInterval : null,
    drawContext : null,
    mouseDown : false,
    gameRunning : false,
    deathText : null,
	velocity : 0,
	
    init: function(canvasId, parentId, options){
        this.container = document.getElementById(parentId);
        if (!this.container) return false;
        for (var optionType in options) {
            for (var subOption in options[optionType]) {
                this.options[optionType][subOption] = options[optionType][subOption];
            }
        };
		this.velocity = this.options.nemo.topSpeed;
        this.canvas = this.createCanvas(canvasId);
        this.initScoring();
        this.drawContext = this.canvas.getContext("2d");
        this.createBG();
        this.resetGameData();
        this.createnemo();
        this.createInitialWalls();
        this.initMouseListener();
    },
    createCanvas: function(canvasId) {
        var canvas = document.createElement("canvas");
        canvas.id = canvasId;
        canvas.width = this.options.canvas.width;
        canvas.height = this.options.canvas.height;
        this.container.appendChild(canvas);
        return canvas;
    },
    createBG: function() {
        var draw = this.drawContext;
        draw.clearRect(0,0,this.options.canvas.width, this.options.canvas.height);
        draw.beginPath();                    
        this.roundedRect(draw, 0, 0, this.options.canvas.width, this.options.canvas.height, 10);
        draw.fillStyle = this.options.colours.bg;
        draw.fill();
    },
    resetGameData: function() {
        this.scores.current = this.scores.elements.current.innerHTML = 0;
        this.gameData.nemo.y = Math.round(this.options.canvas.height/2);
        this.gameData.walls.currentHeight = this.options.walls.startHeight;
        this.gameData.walls.currentStep = this.options.walls.step;
        this.gameData.obstacles.counter = this.options.obstacles.separation - this.options.obstacles.width;
        this.gameData.obstacles.current.length = 0;
        this.gameData.walls.current.length = 0;
        if (!!this.deathText) {
            this.deathText.style.display = "none";
        }
        this.createInitialWalls();
    },
    createnemo: function() {
        var draw = this.drawContext;
        if(this.mouseDown === true) {
            this.gameData.nemo.speed -= this.options.nemo.acceleration;
            if (this.gameData.nemo.speed < -this.options.nemo.topSpeed) this.gameData.nemo.speed = -this.options.nemo.topSpeed;
            this.gameData.nemo.rotation = this.gameData.nemo.rotation - 0.01;
            if (this.gameData.nemo.rotation < -0.25) this.gameData.nemo.rotation = -0.25;
        } else {
            this.gameData.nemo.speed = (this.gameData.nemo.speed + this.options.physics.gravity) * this.options.physics.friction;
            if(this.gameData.nemo.speed > this.options.physics.terminalVelocity) this.gameData.nemo.speed = this.options.physics.terminalVelocity;
            this.gameData.nemo.rotation = this.gameData.nemo.rotation + 0.02;
            if (this.gameData.nemo.rotation > 0) this.gameData.nemo.rotation = 0;
        }
        this.gameData.nemo.y = this.gameData.nemo.y + this.gameData.nemo.speed;
        draw.save();
        draw.translate(this.gameData.nemo.x, this.gameData.nemo.y);
        draw.rotate(this.gameData.nemo.rotation);
        if (this.options.nemo.img) {
            var that = this;
            var nemo = new Image();
            nemo.src = that.options.nemo.img;
            nemo.onload = function() {
                draw.drawImage(nemo, that.gameData.nemo.x, that.gameData.nemo.y, nemo.width, nemo.height);
                that.options.nemo.width = nemo.width;
                that.options.nemo.height = nemo.height;
            }
        } else {
            draw.beginPath();
            this.nemoDraw(draw, 0, 0, this.options.nemo.width, this.options.nemo.height, 10);
            draw.fillStyle = this.options.colours.light;
            draw.fill();
        }
        draw.restore();
    },
    roundedRect: function(draw, x, y, width, height, radius) {
        draw.beginPath();
        draw.moveTo(x,y+radius);
        draw.lineTo(x,y+height-radius);
        draw.quadraticCurveTo(x,y+height,x+radius,y+height);
        draw.lineTo(x+width-radius,y+height);
        draw.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
        draw.lineTo(x+width,y+radius);
        draw.quadraticCurveTo(x+width,y,x+width-radius,y);
        draw.lineTo(x+radius,y);
        draw.quadraticCurveTo(x,y,x,y+radius);
    },
    nemoDraw: function(draw, x, y, width, height, radius) {
        draw.beginPath();
		radius *= 1.5;
		draw.arc(x+radius/2,y-radius/2,radius,Math.PI/6,5*Math.PI/6);
		draw.arc(x+radius/2,y+radius/2,radius,7*Math.PI/6,11*Math.PI/6);
		draw.moveTo(x,y);
		draw.lineTo(x-radius/2,y-radius/2);
		draw.lineTo(x-radius/2,y+radius/2);
		draw.lineTo(x,y);
    },
    initScoring: function() {
        var scoreContainer = document.createElement("b");
        scoreContainer.id = "scorecontainer";
        var scoreContainerText = document.createTextNode("Current score: ");
        scoreContainer.appendChild(scoreContainerText);
        this.scores.elements.current = this.createScore('current');
        scoreContainer.appendChild(this.scores.elements.current);
        scoreContainerText = document.createTextNode(" High score: ");
        scoreContainer.appendChild(scoreContainerText);
        this.scores.elements.top = this.createScore('top');
        scoreContainer.appendChild(this.scores.elements.top);
        this.container.appendChild(scoreContainer);
    },
    createScore: function(scoreType) {
        var score = document.createElement("strong");
        score.id = scoreType+"score";
        var scoreText = document.createTextNode(localStorage.highscore);
        score.appendChild(scoreText);
        return score;
    },
    initMouseListener: function(){
        var that = this;
		document.addEventListener("touchstart",function(event) {
            if (event.target.id == that.canvas.id) {
                that.mouseDown = true;
                if (that.gameRunning === false) {
                    that.startGame();
                }
            }
        });
		document.addEventListener("touchend",function(event) {
            that.mouseDown = false;
        });
        document.onmousedown = function(event) {
            if (event.target.id == that.canvas.id) {
                that.mouseDown = true;
                if (that.gameRunning === false) {
                    that.startGame();
                }
            }
        }
        document.onmouseup = function(event) {
            that.mouseDown = false;
        }
    },
    startGame: function() {
        this.resetGameData();
        this.gameRunning = true;
        this.canvasInterval = setInterval('jsNemo.draw()', this.options.canvas.refreshRate);
    },
    draw: function() {
        var impact = this.checkForImpact();
        if (impact === false) {
            this.createBG();
            this.createnemo();
            this.createWalls();
            this.createObstacles();
            this.updateScore();
        } else {
            this.endGame();
        }
    },
    checkForImpact: function() {
        if (this.gameData.obstacles.current.length >=1) {
            for (var x = this.gameData.obstacles.current.length-1; x >= 0; x--){
                if(
                    this.gameData.obstacles.current[x].x >=this.gameData.nemo.x &&
                    this.gameData.obstacles.current[x].x <= (this.gameData.nemo.x+this.options.obstacles.width)
                ) {
                    if (
                        this.gameData.nemo.y >= this.gameData.obstacles.current[x].y &&
                        this.gameData.nemo.y <= (this.gameData.obstacles.current[x].y + this.options.obstacles.height)
                    ) {
                        return true;
                    }
                }
            }
        }
        for (var i = 0; i < this.gameData.walls.current.length; i++){
            if (this.gameData.walls.current[i].x < this.options.walls.width + this.options.nemo.width) {
                if (
                    (
                        this.gameData.walls.current[0].width == (this.options.canvas.width + this.options.walls.width) || // first wall
                        this.gameData.walls.current[i].x >=0 // all other walls
                    ) && (
                        this.gameData.nemo.y < this.gameData.walls.current[i].height || //top
                        this.gameData.nemo.y > (this.options.canvas.height - this.options.nemo.height - (this.gameData.walls.current[i].y-this.gameData.walls.current[i].height)) // bottom
                    )
                ) {
                    return true;
                }
            }
        }
        if (this.gameData.nemo.y < 0 || this.gameData.nemo.y > (this.options.canvas.height - this.options.nemo.height)) { 
            return true; 
        } 
        return false; 
    },
    createInitialWalls: function() {
        var draw = this.drawContext;
        var newwall = {
            x: 0,
            y: this.gameData.walls.currentHeight,
            width : this.options.canvas.width + this.options.walls.width,
            height : (this.gameData.walls.currentHeight/2)
        }
        this.gameData.walls.current.push(newwall);
        draw.save();
        draw.beginPath();
        draw.fillStyle = this.options.colours.fillBot;
        draw.fillRect(newwall.x, 0, newwall.width, newwall.height);
        draw.fill();
        draw.restore();
        draw.beginPath();
        draw.fillStyle = this.options.colours.fillBot;
        draw.fillRect(newwall.x, this.options.canvas.height-newwall.height, newwall.width, newwall.height);
        draw.fill();
    },
    createWalls: function() {
        var draw = this.drawContext;
        if (this.gameData.walls.counter++ >= Math.floor(this.options.walls.separation/this.options.nemo.topSpeed)) {
            var previousHeight = this.gameData.walls.current[this.gameData.walls.current.length-1].height;
            var plusMinus = Math.round(Math.random());
            var bigOne = Math.round(Math.random()*10);
            var newHeight;
            if (bigOne == 10) {
                newHeight = this.gameData.walls.currentHeight/2;
            } else if (plusMinus == 1) {
                newHeight = previousHeight + Math.floor(Math.random()*this.gameData.walls.currentStep);
            } else {
                newHeight = previousHeight - Math.floor(Math.random()*this.gameData.walls.currentStep);
            }
            if (newHeight > this.gameData.walls.currentHeight) {
                newHeight = this.gameData.walls.currentHeight - this.gameData.walls.currentStep;
            }
            if (newHeight < 0) {
                newHeight = this.gameData.walls.currentStep;
            }
            var newwall = {
                x: this.options.canvas.width,
                y: this.gameData.walls.currentHeight,
                width: this.options.walls.width,
                height: newHeight
            }
            this.gameData.walls.current.push(newwall);
            this.gameData.walls.counter = 0;
        }
        for (var i=0; i < this.gameData.walls.current.length; i++) {
            draw.save();
            draw.beginPath();
            draw.fillStyle = this.options.colours.fillBot;
            draw.fillRect(this.gameData.walls.current[i].x-=this.options.nemo.topSpeed, 0, this.gameData.walls.current[i].width, this.gameData.walls.current[i].height);
            draw.fill();
            draw.restore();
            draw.beginPath();
            draw.fillStyle = this.options.colours.fillBot;
            draw.fillRect(this.gameData.walls.current[i].x, this.options.canvas.height-(this.gameData.walls.current[i].y-this.gameData.walls.current[i].height), this.gameData.walls.current[i].width, this.gameData.walls.current[i].y-this.gameData.walls.current[i].height);
            draw.fill();
            if (this.gameData.walls.current[i].x <= - (2*this.gameData.walls.current[i].width)) {
                this.gameData.walls.current.splice(i, 1);
            }
        }
    },
    createObstacles: function() {
        var draw = this.drawContext;
        if (this.gameData.obstacles.counter++ >= Math.floor(this.options.obstacles.separation/this.options.nemo.topSpeed)) {
            if (
                    this.gameData.walls.currentHeight <= this.options.walls.maxHeight &&
                    this.options.walls.heightIncreaseInterval > 0 && 
                    (this.gameData.walls.heightIncreaseInterval++ == this.options.walls.heightIncreaseInterval)
            ) {
                this.gameData.walls.currentHeight += this.options.walls.heightIncreaseStep;
                this.gameData.walls.currentStep++;
                this.gameData.walls.heightIncreaseInterval = 0;
            }
            var newObstacle = {
                x: this.options.canvas.width,
                y: Math.floor((Math.random() * (this.options.canvas.height - (2*this.gameData.walls.currentHeight))) + (this.gameData.walls.currentHeight/2))
            }
            this.gameData.obstacles.current.push(newObstacle);
            this.gameData.obstacles.counter = 0;
        }
        for (var i=0; i < this.gameData.obstacles.current.length; i++) {

            draw.beginPath();
			var temp = parseFloat(this.gameData.obstacles.current[i].y/parseFloat(this.options.canvas.height/3));
			if (temp < 1.0)
				draw.fillStyle = this.options.colours.fillObs1;
			else if (temp < 2.0)
				draw.fillStyle = this.options.colours.fillObs2;
			else
				draw.fillStyle = this.options.colours.fillObs3;
            this.roundedRect(draw, this.gameData.obstacles.current[i].x-=this.options.nemo.topSpeed, this.gameData.obstacles.current[i].y, this.options.obstacles.width, this.options.obstacles.height, 10);
            draw.fill();
            if (this.gameData.obstacles.current[i].x <= - (this.options.canvas.width)) {
                this.gameData.obstacles.current.splice(i, 1);
            }
        }
    },
    updateScore: function() {
        this.scores.halfStep = (this.scores.halfStep == 0) ? 1 : 0;
        if (this.scores.halfStep == 1) {
            this.scores.current++;
            this.scores.elements.current.innerHTML = this.scores.current;
        }
		this.options.nemo.topSpeed = this.velocity * (1.0+parseFloat(this.scores.current / 100));
    },
    endGame: function() {
        if (this.scores.current > Number(localStorage.highscore)) {
            this.scores.elements.top.innerHTML = this.scores.current;
			this.scores.top = this.scores.current;
localStorage.highscore=this.scores.current.toString();
        } 
        if (!this.deathText) {
           
           alert("                   DEAD !!!");
           navigator.vibrate("1000");
        }
        clearInterval(this.canvasInterval);    
        this.gameRunning = false;
		
    },
    ucFirst: function(textString) {
        return textString;
    }
}