
    var UP = 0;
    var DOWN = 1;
    var RIGHT = 2;
    var LEFT = 3;

    function Frog() {

    	this.SIT_N = 0;
    	this.SIT_S = 1;
    	this.SIT_E = 2;
    	this.SIT_W = 3;

    	this.JUMP_N = 4;
    	this.JUMP_S = 5;
    	this.JUMP_E = 6;
    	this.JUMP_W = 7;

    	this.WATER_N = 8;
    	this.WATER_S = 9;
    	this.WATER_E = 10;
    	this.WATER_W = 11;

    	this.SWIM_N = 12;
    	this.SWIM_S = 13;
    	this.SWIM_E = 14;
    	this.SWIM_W = 15;
    	
    	this.uid = Math.floor(Math.random()*10000);
    	
        this.imgSU = new Image();
        this.imgSU.src = "image?id=5";
        this.imgSD = new Image();
        this.imgSD.src = "image?id=6";
        this.imgSR = new Image();
        this.imgSR.src = "image?id=7";
        this.imgSL = new Image();
        this.imgSL.src = "image?id=8";

        this.imgJU = new Image();
        this.imgJU.src = "image?id=9";
        this.imgJD = new Image();
        this.imgJD.src = "image?id=10";
        this.imgJR = new Image();
        this.imgJR.src = "image?id=11";
        this.imgJL = new Image();
        this.imgJL.src = "image?id=12";

        this.imgWU = new Image();
        this.imgWU.src = "image?id=13";
        this.imgWD = new Image();
        this.imgWD.src = "image?id=15";
        this.imgWR = new Image();
        this.imgWR.src = "image?id=17";
        this.imgWL = new Image();
        this.imgWL.src = "image?id=19";
        
        this.imgWU2 = new Image();
        this.imgWU2.src = "image?id=14";
        this.imgWD2 = new Image();
        this.imgWD2.src = "image?id=16";
        this.imgWR2 = new Image();
        this.imgWR2.src = "image?id=18";
        this.imgWL2 = new Image();
        this.imgWL2.src = "image?id=20";
        
        this.images = [this.imgSU, this.imgSD, this.imgSR, this.imgSL,
                       this.imgJU, this.imgJD, this.imgJR, this.imgJL,
                       this.imgWU, this.imgWD, this.imgWR, this.imgWL,
                       this.imgWU2, this.imgWD2, this.imgWR2, this.imgWL2
                      ];
        

        this.standardHeight = 40;
        this.standardWidth = 40;
        this.timer = 0;
    	this.movementDelta = 0;
    	this.resting = false;
        this.imgId = this.SIT_E;
        this.savedImgId = -1;
        this.position = { 'x' : 0, 'y' : 0 };
        this.moving = false;
        this.direction = RIGHT;
        this.speed = 0.08;
        this.inWater = false;
        
        this.intervalId = 0;
        this.setIntervalForStanding();
        
    }
    
    Frog.prototype.setIntervalForMoving = function() {
    	if (this.intervalId > 0) {
    		clearInterval(this.intervalId);
    	}
        var self = this;
        this.intervalId = setInterval(function() {
        	self.trigger('move', self.getInfo());
        },50);
    }

    Frog.prototype.setIntervalForStanding = function() {
    	if (this.intervalId > 0) {
    		clearInterval(this.intervalId);
    	}
        var self = this;
        this.intervalId = setInterval(function() {
        	self.trigger('move', self.getInfo());
        },1000);
    }
    
    Frog.prototype.destroy = function() {
    	this.uid = -1;
    }

    Frog.prototype.bottom = function() {
    	return this.position.y + 10 - (15 / 2);
    }

    Frog.prototype.setImageByDirection = function(dir, type) {

    	if (!dir) dir = this.direction;
    	if (!type) {
    		type = 0;
    		if (this.inWater) {
    		    type = this.WATER_N;
    	    }
    		if (this.moving && !this.resting) {
    			type += 4;
    		}
    	}
    	this.imgId = dir + type;
    	
    }
    
    Frog.prototype.getInfo = function() {
    	return {id: this.uid, imgId: this.imgId, pos: this.position};
    }
    
    Frog.prototype.stopMoving = function() {
    	this.moving = false;
    	this.resting = false;
    	this.movementDelta = 0;
    	this.setImageByDirection();
        this.setIntervalForStanding();
    	this.trigger('move', this.getInfo());
    }
    
    Frog.prototype.moveUp = function() {
    	this.moving = true;
    	this.direction = UP;
    	this.setImageByDirection();
        this.setIntervalForMoving();
    	this.trigger('move', this.getInfo());
    }

    Frog.prototype.moveDown = function() {
    	this.moving = true;
    	this.direction = DOWN;
    	this.setImageByDirection();
        this.setIntervalForMoving();
    	this.trigger('move', this.getInfo());
    }

    Frog.prototype.moveLeft = function() {
    	this.moving = true;
    	this.direction = LEFT;
    	this.setImageByDirection();
        this.setIntervalForMoving();
    	this.trigger('move', this.getInfo());
    }

    Frog.prototype.moveRight = function() {
    	this.moving = true;
    	this.direction = RIGHT;
    	this.setImageByDirection();
        this.setIntervalForMoving();
    	this.trigger('move', this.getInfo());
    }

    Frog.prototype.update = function(elapsed) {
    	
    	if (this.uid == -1) return;
    	if (this.inArea && currentArea && currentArea.id && this.inArea != currentArea.id) return;
    	
    	if (this.moving && !this.resting) {
    		
        	var movement = elapsed * this.speed;
        	
            var nextPos = { 'x': this.position.x, 'y': this.position.y };
            
        	if (this.direction == UP) {
        		nextPos.y -= movement;
        	} else if (this.direction == DOWN) {
        		nextPos.y += movement;
        	} else if (this.direction == LEFT) {
        		nextPos.x -= movement;
        	} else {
        		nextPos.x += movement;
        	}
        	
        	var gridX = Math.round((nextPos.x + (this.imgSL.width / 2)) / world.tileWidth) - 1; 
        	var gridY = Math.round((nextPos.y + (this.imgSL.height / 2)) / world.tileHeight) - 1;
        	
        	//var whatnot = world.collideWith(new Box(new Point(nextPos.x, nextPos.y+10), 20, 20));
        	var whatnot = world.collideWith(this.getCollisionBox(nextPos.x, nextPos.y));
        	if (whatnot) {
                
        		// debug output - collision
        		if (debug) {
        			console.debug("collision!");
        		}
                
                movement = 0;
                var diff = {x: whatnot.axis.x * whatnot.overlap, y: whatnot.axis.y * whatnot.overlap};
                var npx = nextPos.x - diff.x;
                var npy = nextPos.y - diff.y;
                
                //console.debug("moving x:%d, y:%d", this.position.x - npx, this.position.y - npy);
                
                this.position.x = nextPos.x - diff.x;
                this.position.y = nextPos.y - diff.y;
                
                
        	} else {

        		// debug output - frog grid location
        		if (debug) {
        			console.debug("frog at grid position " + gridX + ", " + gridY);
        		}
        		
                this.position.x = nextPos.x;
            	this.position.y = nextPos.y;
            	
        	}
        	
        	
            var wtr = world.isWaterAt(gridX, gridY);
            if (wtr && !this.inWater) {
            	try {
            		splashSound.play();
            	} catch (e) {
            		// ignore
            	}
            }
        	this.inWater = wtr;
        	
    		this.movementDelta += movement;
    		if (this.movementDelta > 40) {
    			this.movementDelta = 0;
    			this.resting = true;
    			this.timer = 0;
    			this.savedImgId = this.imgId;
    		}

    		this.setImageByDirection();

    	} else if (this.resting) {
    		this.timer += elapsed;
    		if (this.timer >= 500) {
    			this.resting = false;
    			this.imgId = this.savedImgId;
    			this.timer = 0;
    		}
    	}


    }
    
    Frog.prototype.getCollisionBox = function(x, y) {
    	
    	return new Box(new Point(x + 0, y + 10), 30, 15);
    	
    }
    
    Frog.prototype.draw = function(ctx) {

    	if (this.uid == -1) return;
    	if (this.inArea && currentArea && currentArea.id && this.inArea != currentArea.id) return;
    	
        ctx.save();

        ctx.translate((this.position.x),(this.position.y));
        if (debug)  {
        	var fb = this.getCollisionBox(0, 0);
            fb.poly.draw(ctx);
            ctx.globalAlpha=0.5;
        }
        ctx.drawImage(this.images[this.imgId],-(this.images[this.imgId].width/2),-(this.images[this.imgId].height/2));
        if (debug) {
        	ctx.globalAlpha=1.0;
        }

        ctx.restore();
        
    }
    
    MicroEvent.mixin(Frog);


