// Copyright 2005-2006 Jim Radford <radford@blackbean.org> -*- c -*-
// Copyright 2005-2006 David Caldwell <david@porkrind.org>
function img(source,r,c,width,height){image=document.createElement("img");image.src=source;image.style.width=px(width);image.style.height=px(height);image.width=width;image.height=height;image.style.position="absolute";image.style.left=px(c);image.style.top=px(r);image.style.border="0";return image;}
function img_move(img,r,c){img.style.left=px(c);img.style.top=px(r);}
function SetTextContents(div,text){while(div.firstChild)
div.removeChild(div.firstChild);div.appendChild(document.createTextNode(text));}
function HighScore(div,tabs_div,game){function interval(days){return{days:days}};var timeframe={"Today":interval(1),"This Week":interval(7),"This Month":interval(30),"All Time":interval("all")};for(var t in timeframe){tabs_div.appendChild(timeframe[t].td=doc.el("td",{},doc.el("a",{href:"#",onclick:wrap(this,function(t){return wrap(this,function(){this.switch_timeframe(t);return false;})})(t)},doc.text(t))));}
this.switch_timeframe=function(new_t){for(var t in timeframe)
timeframe[t].td.className=t==new_t?"selected":undefined;this.days=timeframe[new_t].days;this.timeframe=new_t;this.refresh();}
this.render=function(scores,play_id){SetTextContents(div,Login.is_logged_in()?"":"   (log in or create a new user at the top of the page to get a high score)");append_highscores(div,scores,play_id);}
this.load=function(){SetTextContents(div,"Loading High Scores...");};this.refresh=function(play_id,seed){if(play_id==undefined)play_id=this.play_id;else this.play_id=play_id;if(seed==undefined)seed=this.seed;else this.seed=seed;if(seed==undefined)seed=0;SetTextContents(div,"Loading High Scores...");highscore_day(game,this.days,play_id==undefined?{}:{include:play_id},wrap(this,function(scores,error,status){this.render(scores,play_id)}));};this.switch_timeframe("This Week");return this;}
var blocksize=20;function Sirtet(board_div,next_div,score_div,level_div,lines_div,highscore_div,highscoretabs_div,start_div,pause_div,next_toggle_div,slow_drop_div){this.name="sirtet";this.div={};this.div.board=board_div;this.div.next=next_div;this.div.start_button=start_div;this.div.pause_button=pause_div;this.div.next_checkbox=next_toggle_div;this.div.slow_drop_checkbox=slow_drop_div;this.div.start_button.onclick=wrap(this,function(){this.new_game();});this.init_keyboard_focus_auto_pause(this.div.board,this.div.pause_button,function(){return!this.gameover});this.div.next_checkbox.onclick=wrap(this,function(){this.next_toggle(this.div.next_checkbox.checked);});this.stats=new stats(this.name);this.score=new Stat(score_div,"score",this.stats);this.level=new Stat(level_div,"level",this.stats);this.lines=new Stat(lines_div,"lines",this.stats);this.high_score=new HighScore(highscore_div,highscoretabs_div,this.name);this.blocks=new Array(22);this.next_toggle(1);this.gameover=undefined;this.bottom_tolerance=1;this.register_key_events(function(event){switch(event.key){case"+":this.resize(++blocksize);return false;case"-":this.resize(--blocksize);return false;}
if(this.gameover)return true;switch(event.key){case"k":case"up":if(!this.paused){this.rotate();return false;}break;case"space":if(!this.paused){this.drop();return false;}break;case"down":if(!this.paused){if(this.slow_drop())this.down();else this.drop();return false;}break;case"j":case"left":if(!this.paused){this.left();return false;}break;case"l":case"right":if(!this.paused){this.right();return false;}break;case"p":case"escape":this.key_pause();return false;case"n":this.next_toggle();return false;case"i":if(!this.paused){this.level.get()<9&&this.level.inc(1);return false;}break;}},"keydown");this.resize=function(size){blocksize=size=size>32?32:size<10?10:size;this.div.board.style.height=px(22*size);this.div.board.style.width=px(10*size);this.div.next.parentNode.style.height=this.div.next.style.height=px(2*size);this.div.next.style.width=px(4*size);if(this.gameover){this.gameover.style.width=px(10*size);this.gameover.style.height=px(5*size);this.gameover.style.top=px(9*size);}
if(this.paused){this.paused_div.style.width=px(10*size);this.paused_div.style.height=px(5*size);this.paused_div.style.top=px(9*size);}
this.pieces_reset();this.pieces_generate();this.update();if(this.piece!=undefined){this.pieces[this.piece][this.orient].hide();this.pieces[this.piece][this.orient].move(this.r,this.c);this.pieces[this.piece][this.orient].show(this.div.board);}
if(this.next!=undefined){this.pieces_next[this.next].hide();this.pieces_next[this.next].show(this.div.next);}};window.onresize=wrap(this,function(){this.resize(Math.floor(plat.windowHeight()*.80/22))});window.onresize();}
Sirtet.prototype=new KeyboardFocusAutoPause();var north=1<<0,east=1<<1,south=1<<2,west=1<<3;function square(color,r,c,edge){this.color=color;this.r=r;this.c=c;this.edge=edge;return this;}
square.prototype.copy=function(){return new square(this.color,this.r,this.c,this.edge);}
var color_map=["red","purple","aqua","yellow","orange","blue","green","grey","maroon"];var edge_map=(function(){var map=[];for(var i=0;i<16;i++)
map[i]=(i&north?"n":"")+(i&south?"s":"")+(i&east?"e":"")+(i&west?"w":"");return map;})();square.prototype.source=function(){return"blocks/"+color_map[this.color]+"-"+blocksize+"-"+edge_map[this.edge]+".png";}
square.prototype.move=function(r,c){this.r=r;this.c=c;if(this.img)
img_move(this.img,r*blocksize,c*blocksize);}
square.prototype.show=function(div){if(this.img==undefined)
this.img=img(this.source(),this.r*blocksize,this.c*blocksize,blocksize,blocksize);div.appendChild(this.img);}
square.prototype.hide=function(){this.img.parentNode.removeChild(this.img)}
square.prototype.same=function(grid,r,c){return r>=0&&r<grid.length&&grid[r]&&c>=0&&c<grid[r].length&&grid[r][c]&&this.color==grid[r][c].color;}
square.prototype.toString=function(){return""+this.color+":"+this.edge+"("+this.c+","+this.r+")";}
square.prototype.chamfer=function(grid,r,c,edges){var edge=(this.same(grid,r-1,c)?north:0)|(this.same(grid,r+1,c)?south:0)|(this.same(grid,r,c-1)?west:0)|(this.same(grid,r,c+1)?east:0);if(edges==undefined)edges=0xf;if((edge&edges)!=(this.edge&edges)){this.edge=(this.edge&~edges)|(edge&edges);if(this.img)this.img.src=this.source();}}
function piece(color,coords){this.color=color;this.squares=[];for(var i in coords)
this.squares.push(new square(color,coords[i][0],coords[i][1]));var grid=[[],[],[],[]];for(var s in this.squares)
grid[this.squares[s].r][this.squares[s].c]=this.squares[s];chamfer(grid);this.div=doc.el("div",{style:{position:"absolute"}});for(var i in this.squares)
this.squares[i].show(this.div);return this;}
piece.prototype.move=function(r,c){this.div.style.top=px(r*blocksize);this.div.style.left=px(c*blocksize);return this;}
piece.prototype.show=function(div){div.appendChild(this.div);return this.div;}
piece.prototype.hide=function(){if(this.div.parentNode)this.div.parentNode.removeChild(this.div);return this.div;}
Sirtet.prototype.pieces_generate=function(){var d=[{sym:2,rc:[[1,0],[1,1],[1,2],[1,3]],o:[1,2]},{sym:4,rc:[[1,0],[1,1],[1,2],[0,2]],o:[1,1]},{sym:2,rc:[[1,1],[1,2],[0,2],[0,3]],o:[1,2]},{sym:4,rc:[[0,1],[1,1],[1,2],[1,3]],o:[1,2]},{sym:2,rc:[[0,0],[0,1],[1,1],[1,2]],o:[1,1]},{sym:1,rc:[[0,1],[0,2],[1,1],[1,2]],o:[1,1]},{sym:4,rc:[[1,0],[1,1],[0,1],[1,2]],o:[1,1]}];this.pieces=[];this.pieces_next=[];for(var color=0;color<d.length;color++){this.pieces[color]=[];this.pieces_next[color]=new piece(color,d[color].rc);for(var o=0;o<d[color].sym;o++){this.pieces[color].push(new piece(color,d[color].rc));for(var s in d[color].rc){var r=d[color].rc[s][0],c=d[color].rc[s][1];var or=d[color].o[0],oc=d[color].o[1];d[color].rc[s]=[or-(c-oc),oc+(r-or)];}}}}
Sirtet.prototype.pieces_reset=function(){if(this.pieces)
for(var color=0;color<this.pieces.length;color++){this.pieces_next[color].hide();for(var o=0;o<this.pieces[color].length;o++)
this.pieces[color][o].hide();}}
function chamfer_row(grid,r,edges){if(r>=0&&r<grid.length)
for(var c=0;c<grid[r].length;c++)
grid[r][c]&&grid[r][c].chamfer(grid,r,c,edges);return true;}
function chamfer(grid){for(var r=0;r<grid.length;r++)
chamfer_row(grid,r);}
Sirtet.prototype.remove=function(r,c){if(this.blocks[r][c]){this.blocks[r][c].hide();delete this.blocks[r][c];}}
Sirtet.prototype.remove_all=function(){for(var r=0;r<this.blocks.length;r++)
if(this.blocks[r])
for(var c=0;c<this.blocks[r].length;c++)
this.remove(r,c);}
Sirtet.prototype.empty=function(r,c){return r>=0&&r<this.blocks.length&&c>=0&&c<this.blocks[r].length&&this.blocks[r][c]==undefined;}
Sirtet.prototype.fits=function(piece,r,c){for(var s=0;s<piece.squares.length;s++){var sq=piece.squares[s];if(!this.empty(r+sq.r,c+sq.c))
return;}
return piece;}
Sirtet.prototype.down=function(){return this.move(1,0,0)}
Sirtet.prototype.left=function(){return this.move(0,-1,0)}
Sirtet.prototype.right=function(){return this.move(0,1,0)}
Sirtet.prototype.rotate=function(){return this.move(0,0,1)}
Sirtet.prototype.move=function(dr,dc,i){var o=(this.orient+i)%this.pieces[this.piece].length
var piece=this.pieces[this.piece][o];if(!this.fits(piece,this.r+dr,this.c+dc)){if(i&&this.fits(piece,this.r+dr,this.c+dc+1))dc++;else if(i&&this.fits(piece,this.r+dr,this.c+dc-1))dc--;else return;}
piece.move(this.r+=dr,this.c+=dc);if(this.orient!=o){this.pieces[this.piece][this.orient].hide();this.pieces[this.piece][o].show(this.div.board);this.orient=o;}
return true;}
Sirtet.prototype.drop=function(){cancel_timeout(this.timeout);var piece=this.pieces[this.piece][this.orient];for(var i=0;this.fits(piece,this.r+i+1,this.c);i++);this.score.inc(i*(this.level.get()+1));this.move(i,0,0);this.bottom=this.bottom_tolerance;this.step(true);}
Sirtet.prototype.update=function(){for(var r=0;r<this.blocks.length;r++)
if(this.blocks[r])
for(var c=0;c<this.blocks[r].length;c++)
if(this.blocks[r][c]){this.blocks[r][c].hide();this.blocks[r][c].img=undefined;this.blocks[r][c].show(this.div.board);}}
Sirtet.prototype.move_to=function(square,r,c){this.blocks[r][c]=square;square&&square.move(r,c);square&&square.show(this.div.board);}
Sirtet.prototype.remove=function(r){for(var c=0;c<this.blocks[r].length;c++)
this.blocks[r][c]&&this.blocks[r][c].hide();var removed=this.blocks[r];this.blocks[r]=Array(10);return removed;}
Sirtet.prototype.insert=function(r,row){for(var c=0;c<row.length;c++)
this.move_to(row[c],r,c);}
Sirtet.prototype.merge=function(){var n,piece=this.pieces[this.piece][this.orient];for(var s=0;s<piece.squares.length;s++){var sq=piece.squares[s].copy();this.move_to(sq,this.r+sq.r,this.c+sq.c);}
piece.hide();var full=0,chamfered=false;for(var r=this.blocks.length-1;r>=0;r--){for(var c=0;c<this.blocks[r].length;c++)
if(this.empty(r,c))
break;if(c==this.blocks[r].length){full++;this.remove(r);if(!chamfered)chamfered=chamfer_row(this.blocks,r+full,north);}else{if(chamfered)chamfered=!chamfer_row(this.blocks,r,south);full&&this.insert(r+full,this.remove(r));}}
this.score.inc((1<<full)*(this.level.get()+(this.show_next||this.seen_next?1:5)));this.seen_next=false;this.faster(this.lines.inc(full));}
Sirtet.prototype.faster=function(lines){var level=this.level.get();if(level<6&&lines>(level+1)*10)level=this.level.inc(1);if(level==6&&lines>74)this.level.set(7);if(level==7&&lines>89)this.level.set(8);if(level==8&&lines>104)this.level.set(9);}
Sirtet.prototype.pick_next=function(){this.piece=this.next;if(this.piece==undefined)
this.piece=Math.floor(Math.random()*this.pieces.length);this.orient=0;this.r=0;this.c=3;if(this.next!=undefined)
this.pieces_next[this.next].hide();this.next=Math.floor(Math.random()*this.pieces.length);this.pieces_next[this.next].show(this.div.next);var piece=this.pieces[this.piece][this.orient];if(this.fits(piece,this.r,this.c)){piece.move(this.r,this.c);piece.show(this.div.board);}else{this.piece=this.orient=undefined;cancel_timeout(this.timeout);this.gameover=img("hopeless/gameover.png",blocksize*9,0,10*blocksize,5*blocksize);this.gameover.style.zIndex=2;this.div.board.appendChild(this.gameover);this.div.pause_button.disabled=true;this.stats.done(wrap(this,function(play_id,error){if(error)new_text_alert(error);else this.high_score.refresh(play_id);}));}}
var delay=[70,67,55,40,34,25,20,18,14,9,5];Sirtet.prototype.step=function(move){if(move&&!this.down()&&this.bottom++==this.bottom_tolerance){this.bottom=0;this.merge();this.pick_next();}
if(!this.gameover)
this.timeout=timeout((delay[this.level.get()]+(this.r<3?10:0))*10,wrap(this,function(){this.step(true);}));}
Sirtet.prototype.on_pause=function(){cancel_timeout(this.timeout);this.paused_div=img("hopeless/paused.png",blocksize*9,0,10*blocksize,5*blocksize);this.paused_div.style.zIndex=2;this.div.board.appendChild(this.paused_div);}
Sirtet.prototype.on_unpause=function(){this.paused_div.parentNode.removeChild(this.paused_div);this.paused_div=undefined;this.step();}
Sirtet.prototype.slow_drop=function(){return this.div.slow_drop_checkbox.checked;}
Sirtet.prototype.next_toggle=function(value){this.show_next=value==undefined?!this.show_next:value;this.seen_next|=this.show_next;this.div.next.style.display=this.show_next?"block":"none";if(this.div.next_checkbox.checked!=value)this.div.next_checkbox.checked=value;}
Sirtet.prototype.new_game=function(seed){this.seed=gotd.pick_seed(seed);srand(this.seed);this.game_id=(new Date()).getTime()+Math.random();this.stats.start();this.stats.set("seed",this.seed);this.stats.set("game_id",this.game_id);if(this.paused)this.pause(false);if(this.timeout)cancel_timeout(this.timeout);this.remove_all();this.pieces_reset();if(this.gameover!=undefined){this.gameover.parentNode.removeChild(this.gameover);this.gameover=undefined;}
this.div.pause_button.disabled=false;for(var x=0;x<this.blocks.length;x++)
this.blocks[x]=new Array(10);this.score.set(0);this.level.set(0);this.lines.set(0);this.bottom=0;this.pick_next();this.step();this.input_focus();}
var the_game=new Sirtet(doc.id("board"),doc.id("next"),doc.id("score"),doc.id("level"),doc.id("lines"),doc.id("global_high_score"),doc.id("scoretab"),doc.id("start"),doc.id("pause"),doc.id("next_toggle"),doc.id("slow_drop"));the_game.new_game(URL.param.game);gotd.start=function(){the_game.new_game(game_of_the_day);return false;};