var Pentagoo=new Class({Implements:[Events,Options],options:{size:6,subboardSize:3,winLength:5,aiURL:'pentagoo_ai.php',imagesPath:'styles/images/',images:['white-marble.png','black-marble.png','space-select.png','rotate-arrows.png','pentago-subboard-15deg.png','pentago-subboard-30deg.png','pentago-subboard-45deg.png','pentago-subboard-60deg.png','pentago-subboard-75deg.png','marble-select.png','highlight-marble.png','pointer.png']},initialize:function(options){this.setOptions(options);this.initStuff();this.generateEvents();this.preloadStuff();},initStuff:function(){this.boardMatrix=[];for(var y=0;y<this.options.size;y++){this.boardMatrix[y]=[];for(var x=0;x<this.options.size;x++)
this.boardMatrix[y][x]=0;}
this.moveHistory=[];this.lastMarbleHistory=[];this.lastMarble=null;this.gameType=0;this.computerLevel=[0,0];this.game=0;this.currentHistory=null;this.boardMatrixCopy=[];this.highlightMarble=this.highlightRotate='00';this.boardState=0;this.moveState=0;$('undo-link').addClass('disabled');$('history-link').addClass('disabled');$$('.subboard td').setProperty('class','space');this.boardCover(false);this.player=1;$('player-1-label').addClass('current');$('player-2-label').removeClass('current');this.playerType=1;$$('.rotation-buttons').setStyle('opacity',0);$$('.subboard').setStyle('opacity',1);if(!window.ie)$$('.panel').setStyle('opacity','.85');this.cmove=[];this.setStatus();},generateEvents:function(){var self=this;$('new-game-link').addEvent('click',function(){if(!this.hasClass('disabled'))self.slidePanel('new-game');});$('cancel-game-link').addEvent('click',function(){self.slidePanel('new-game');});$('start-game-link').addEvent('click',function(){self.slidePanel('new-game');self.newGame();});$('undo-link').addEvent('click',function(){if(!this.hasClass('disabled')){self.slidePanel();self.historyBack('undo');}});$('history-link').addEvent('click',function(){if(!this.hasClass('disabled'))self.slidePanel('history');});$('history-start-link').addEvent('click',function(){if(!this.disabled)self.historyStart();});$('history-back-link').addEvent('click',function(){if(!this.disabled)self.historyBack();});$('history-forward-link').addEvent('click',function(){if(!this.disabled)self.historyForward();});$('history-end-link').addEvent('click',function(){if(!this.disabled)self.historyEnd();});$('close-history-link').addEvent('click',function(){if(!this.disabled){self.historyEnd();self.slidePanel('history');}});$('rules-link').addEvent('click',function(){if(!this.hasClass('disabled'))self.slidePanel('rules');});$('close-rules-link').addEvent('click',function(){self.slidePanel('rules');});$('about-link').addEvent('click',function(){if(!this.hasClass('disabled'))self.slidePanel('about');});$('close-about-link').addEvent('click',function(){self.slidePanel('about');});$$('.subboard td').addEvent('click',function(){if(self.highlightMarble)$('s-'+self.highlightMarble).removeClass('highlight');var y=this.id.charAt(2).toInt();var x=this.id.charAt(3).toInt();self.place(x,y);self.highlightMarble=''+y+x;}).addEvent('mousemove',function(){if(this.hasClass('space')){if(self.highlightMarble)$('s-'+self.highlightMarble).removeClass('highlight');var y=this.id.charAt(2);var x=this.id.charAt(3);self.highlightMarble=''+y+x;$('s-'+self.highlightMarble).addClass('highlight');}}).addEvent('mouseleave',function(){if(self.highlightMarble)$('s-'+self.highlightMarble).removeClass('highlight');});$$('.rotate-left').each(function(elem,i){elem.addEvent('click',function(){self.rotate((i+1),'l');});});$$('.rotate-right').each(function(elem,i){elem.addEvent('click',function(){self.rotate((i+1),'r');});});$$('.rotate-left','.rotate-right').addEvent('mousemove',function(){if(self.highlightRotate)$('rb-'+self.highlightRotate).removeClass('highlight');var y=this.id.charAt(3);var x=this.id.charAt(4);self.highlightRotate=''+y+x;$('rb-'+self.highlightRotate).addClass('highlight');}).addEvent('mouseleave',function(){if(self.highlightRotate)$('rb-'+self.highlightRotate).removeClass('highlight');});document.addEvent('keydown',function(e){var e=new Event(e);var arrows=['up','down','left','right'];if(e.key=='u'){e.stop();$('undo-link').fireEvent('click');}
else if(arrows.contains(e.key)){e.stop();if(self.playerType==1&&!self.game&&self.boardState==0){if(self.highlightMarble)$('s-'+self.highlightMarble).removeClass('highlight');if(self.highlightRotate)$('rb-'+self.highlightRotate).removeClass('highlight');if(self.moveState==0){var y=self.highlightMarble.charAt(0).toInt();var x=self.highlightMarble.charAt(1).toInt();switch(e.key){case arrows[0]:(y==0)?y=self.options.size-1:y--;break;case arrows[1]:(y==self.options.size-1)?y=0:y++;break;case arrows[2]:(x==0)?x=self.options.size-1:x--;break;case arrows[3]:(x==self.options.size-1)?x=0:x++;break;}
self.highlightMarble=''+y+x;$('s-'+self.highlightMarble).addClass('highlight');}
else{var y=self.highlightRotate.charAt(0).toInt();var x=self.highlightRotate.charAt(1).toInt();switch(e.key){case arrows[0]:(y==0)?y=1:y--;break;case arrows[1]:(y==1)?y=0:y++;break;case arrows[2]:(x==0)?x=3:x--;break;case arrows[3]:(x==3)?x=0:x++;break;}
self.highlightRotate=''+y+x;$('rb-'+self.highlightRotate).addClass('highlight');}}}
else if(e.key=='enter'){e.stop();if(self.playerType==1&&!self.game&&self.boardState==0){if(self.highlightMarble)$('s-'+self.highlightMarble).removeClass('highlight');if(self.highlightRotate)$('rb-'+self.highlightRotate).removeClass('highlight');if(self.moveState==0)
$('s-'+self.highlightMarble).fireEvent('click');else
$('rb-'+self.highlightRotate).fireEvent('click');}}});},preloadStuff:function(){var path=this.options.imagesPath;var oimages=this.options.images;var images=[];for(var i=0;i<oimages.length;i++)images.push(path+oimages[i]);this.boardCover(true);var self=this;new Asset.images(images,{onProgress:function(i){var load_percent=Math.round((i+1)/images.length*100);if(i<images.length)self.setStatus('Loading... ('+load_percent+'%)');},onComplete:function(){self.setStatus();self.boardCover(false);}});},slidePanel:function(panel){$$('#menu a').removeClass('focus');if(panel){var panel_effect=new Fx.Tween(panel,{duration:200});if($(panel).getStyle('width').toInt()==0){$(panel+'-link').addClass('focus');this.boardCover(true);panel_effect.start('width',520);}
else{$(panel+'-link').removeClass('focus');if(!this.game)this.boardCover(false);panel_effect.start('width',0);}}
var panels=$$('.panel[id!='+panel+']');panels.setStyle('width',0);},newGame:function(){this.cmove.each(function(move){$clear(move);});this.initStuff();this.gameType=0;$('player-1-type').set('text','Human');$('player-2-type').set('text','Human');if($('p1-c-l').checked){this.gameType=1;this.playerType=2;this.computerLevel[0]=$('p1-cl').selectedIndex;$('player-1-type').set('text','Computer');this.computerMove();}
if($('p2-c-l').checked){this.computerLevel[1]=$('p2-cl').selectedIndex;this.gameType=(this.gameType==1)?2:1;$('player-2-type').set('text','Computer');}},place:function(x,y){var valid_move=this.movePlace(x,y)&&this.updateHistory(this.move+y+x);if(valid_move){this.checkWin();if(!this.game&&this.playerType==1){this.rotateButtons(1);if(this.moveHistory.length&&this.gameType==0)
$('undo-link').removeClass('disabled');}}},movePlace:function(x,y){this.move='p';var space=$('s-'+y+x);if(this.boardMatrix[y][x]==0){if(this.lastMarble)$('s-'+this.lastMarble).removeClass('last');this.boardMatrix[y][x]=this.player;space.className='p'+this.player;this.lastMarble=''+y+x;space.addClass('last');return true;}
return false;},moveUnplace:function(x,y){var space=$('s-'+y+x);if(this.boardMatrix[y][x]!=0){this.boardMatrix[y][x]=0;space.className='space';this.lastMarble=this.lastMarbleHistory[this.currentHistory-1];if(this.lastMarble)$('s-'+this.lastMarble).addClass('last');return true;}
return false;},rotate:function(subboard,direction){this.boardCover(true);$('undo-link').addClass('disabled');if(this.playerType==1)this.rotateButtons(0);var time=this.moveRotate(subboard,direction);(function(){var valid_move=this.updateHistory(this.move+subboard+direction);if(valid_move){this.checkWin();if(!this.game){this.switchPlayer();if(this.playerType==1){if(this.gameType==0){this.boardCover(false);$('undo-link').removeClass('disabled');}
else if(this.gameType==1){this.playerType=2;this.computerMove();}}
else if(this.playerType==2){if(this.gameType==1){this.playerType=1;this.boardCover(false);}
else if(this.gameType==2)this.computerMove();}}}}.bind(this)).delay(time);},moveRotate:function(subboard,direction){this.move='r';var matrix=[];var init_last=false;var sx=(subboard==2||subboard==4)?this.options.subboardSize:0;var sy=(subboard==3||subboard==4)?this.options.subboardSize:0;for(var y=0;y<this.options.subboardSize;y++){matrix[y]=[];for(var x=0;x<this.options.subboardSize;x++)
matrix[y][x]=this.boardMatrix[y+sy][x+sx];}
if(direction=='r'){for(var y=0;y<this.options.subboardSize;y++)
for(var x=0;x<this.options.subboardSize;x++){this.boardMatrix[y+sy][x+sx]=matrix[(2-x)][y];if(this.lastMarble==''+(2-x+sy)+(y+sx)&&!init_last){this.lastMarble=''+(y+sy)+(x+sx);init_last=true;}}}
else if(direction=='l'){for(var y=0;y<this.options.subboardSize;y++)
for(var x=0;x<this.options.subboardSize;x++){this.boardMatrix[y+sy][x+sx]=matrix[x][(2-y)];if(this.lastMarble==''+(x+sy)+(2-y+sx)&&!init_last){this.lastMarble=''+(y+sy)+(x+sx);init_last=true;}}}
return this.subboardRotationFx(subboard,direction);},moveUnrotate:function(subboard,direction){var reverse_direction=(direction=='l')?'r':'l';return this.moveRotate(subboard,reverse_direction);},subboardRotationFx:function(subboard,direction){var div=$('sb-'+subboard).getParent();var FRAMES=6;var PERIOD=32;var opac;var mid_frame=FRAMES/2;var sx=(subboard==2||subboard==4)?this.options.subboardSize:0;var sy=(subboard==3||subboard==4)?this.options.subboardSize:0;var k=1;var rotate_bg=(function(){if(k==FRAMES){$clear(rotate_bg);div.className='';$('sb-'+subboard).setStyle('opacity',1);return;}
else{div.className='subboard-'+((direction=='l')?k:FRAMES-k);opac=Math.abs(mid_frame-k)/mid_frame;$('sb-'+subboard).setStyle('opacity',opac);if(k==Math.round(mid_frame)){for(var y=sy;y<this.options.subboardSize+sy;y++)
for(var x=sx;x<this.options.subboardSize+sx;x++)
$('s-'+y+x).className=(this.boardMatrix[y][x])?'p'+this.boardMatrix[y][x]:'space';if(this.lastMarble)$('s-'+this.lastMarble).addClass('last');}}
k++;}.bind(this)).periodical(PERIOD);return PERIOD*FRAMES;},updateHistory:function(move_type){var last_index=this.moveHistory.length;var this_move=move_type.charAt(0);var even_index=last_index-(last_index%2);var linear_index=even_index/2;var current_player=(linear_index%2)?2:1;if(((last_index%2==0&&this_move=='p')||(last_index%2!=0&&this_move=='r'))&&this.player==current_player){this.moveHistory.push(move_type);this.lastMarbleHistory.push(this.lastMarble);return true;}
else{this.boardCover(true);$('undo-link').addClass('disabled');this.setStatus('Sorry, an error has occured. Please start a new game.');return false;}},switchPlayer:function(){var prevPlayer=this.player;this.player=(this.player==1)?2:1;$('player-'+prevPlayer+'-label').removeClass('current');$('player-'+this.player+'-label').addClass('current');},rotateButtons:function(show){var rotationButton=$$('.rotation-buttons');var opac=rotationButton[0].getStyle('opacity');if(show&&opac==0){rotationButton.setStyle('opacity','.4');this.moveState=1;}
else if(!show&&opac>0){rotationButton.setStyle('opacity',0);this.moveState=0;}},boardCover:function(state){var cover=$('board-cover');cover.setStyle('z-index',(state)?100:0);this.boardState=(state)?1:0;},historyStart:function(){if(this.currentHistory!=-1){this.currentHistory=-1;this.setStatus();$$('#menu a[id!=history-link]').addClass('disabled');if(this.game){this.game=0;if(!this.boardMatrixCopy.length)
for(var y=0;y<this.options.size;y++){this.boardMatrixCopy[y]=[];for(var x=0;x<this.options.size;x++)
this.boardMatrixCopy[y][x]=this.boardMatrix[y][x];}}
for(var y=0;y<this.options.size;y++)
for(var x=0;x<this.options.size;x++)
this.boardMatrix[y][x]=0;$$('.subboard td').setProperty('class','space');this.player=1;$('player-1-label').addClass('current');$('player-2-label').removeClass('current');this.updateHistoryPointer();}},historyBack:function(action){var current_action;if(action=='undo'){this.currentHistory=this.moveHistory.length-1;current_action=this.moveHistory.getLast();}
else{if(this.currentHistory==null)this.currentHistory=this.moveHistory.length-1;current_action=this.moveHistory[this.currentHistory];}
if(current_action&&this.currentHistory!=null){var prev_game;this.setStatus();$('undo-link').addClass('disabled');if(!$defined(action)){$$('.history-buttons button').setProperty('disabled','disabled');$$('#menu a[id!=history-link]').addClass('disabled');}
var move_type=current_action.split('');var this_move=move_type[0];var move_action1=move_type[1];var move_action2=move_type[2];if(this.game){this.game=0;prev_game=1;$$('.subboard td').removeClass('win');if(action=="undo"){this.boardCover(false);$('history-link').addClass('disabled');}
else if(!this.boardMatrixCopy.length){for(var y=0;y<this.options.size;y++){this.boardMatrixCopy[y]=[];for(var x=0;x<this.options.size;x++)
this.boardMatrixCopy[y][x]=this.boardMatrix[y][x];}}
$('player-'+this.player+'-label').addClass('current');}
if(this_move=='p'){var y=move_action1.toInt();var x=move_action2.toInt();var valid_move=this.moveUnplace(x,y);if(valid_move){if(action=='undo'){this.rotateButtons(0);$('undo-link').removeClass('disabled');}
else
$$('.history-buttons button').removeProperty('disabled');}}
else if(this_move=='r'){var t=move_action1.toInt();var d=move_action2;var time=this.moveUnrotate(t,d);(function(){if(!prev_game)this.switchPlayer();if(action=='undo'){this.rotateButtons(1);$('undo-link').removeClass('disabled');}
else
$$('.history-buttons button').removeProperty('disabled');}.bind(this)).delay(time);}
if(action=="undo"){this.currentHistory=null;this.moveHistory.pop();this.lastMarbleHistory.pop();if(!this.moveHistory.length)$('undo-link').addClass('disabled');}
else if(this.currentHistory>=0)
this.currentHistory--;this.updateHistoryPointer();}},historyForward:function(){var last_index=this.moveHistory.length-1;if(this.currentHistory!=null&&this.currentHistory<last_index)this.currentHistory++;var current_action=this.moveHistory[this.currentHistory];if(current_action&&this.currentHistory!=null){this.setStatus();$$('#menu a[id!=history-link]').addClass('disabled');$$('.history-buttons button').setProperty('disabled','disabled');var move_type=current_action.split('');var this_move=move_type[0];var move_action1=move_type[1];var move_action2=move_type[2];if(this_move=='p'){var y=move_action1.toInt();var x=move_action2.toInt();var valid_move=this.movePlace(x,y);if(valid_move){this.checkWin();if(this.game)this.currentHistory=null;$$('.history-buttons button').removeProperty('disabled');}}
else if(this_move=='r'){var t=move_action1.toInt();var d=move_action2;var time=this.moveRotate(t,d);(function(){this.checkWin();if(this.game)this.currentHistory=null;else this.switchPlayer();$$('.history-buttons button').removeProperty('disabled');}.bind(this)).delay(time);}
this.updateHistoryPointer();}},historyEnd:function(){if(this.boardMatrixCopy.length){for(var y=0;y<this.options.size;y++)
for(var x=0;x<this.options.size;x++){this.boardMatrix[y][x]=this.boardMatrixCopy[y][x];$('s-'+y+x).className=this.boardMatrix[y][x]?'p'+this.boardMatrix[y][x]:'space';}
this.boardMatrixCopy=[];this.currentHistory=null;this.move=(this.moveHistory.getLast().charAt(0)=='r')?'r':'p';this.checkWin();$$('#menu a').removeClass('disabled');if(this.gameType>0)$('undo-link').addClass('disabled');var last_index=this.moveHistory.length-1;var even_index=last_index-(last_index%2);var linear_index=even_index/2;this.player=(linear_index%2)?2:1;this.updateHistoryPointer();}},updateHistoryPointer:function(){var historyPointer=$('history-pointer');if(this.currentHistory==null)
historyPointer.setStyle('left','100%');else{var pointer_position=(this.currentHistory+1)/this.moveHistory.length*100;historyPointer.setStyle('left',pointer_position+'%');}},historyPlay:function(state){var PERIOD=1000;if(state&&this.currentHistory!=null)
this.playSteps=this.historyForward.periodical(PERIOD);else
$clear(this.playSteps);},checkWin:function(){var check_points=this.options.size-this.options.winLength+1;for(var i=0;i<this.options.size;i++)
for(var j=0;j<check_points;j++){this.checkWinningMarbles(j,i,'horizontal');this.checkWinningMarbles(i,j,'vertical');}
for(var k=0;k<check_points;k++)
for(var l=0;l<check_points;l++){this.checkWinningMarbles(k,l,'l-diagonal');this.checkWinningMarbles((k+4),l,'r-diagonal');}
var draw=(this.move=='r'&&!this.boardMatrix.toString().contains(0))?1:0;if(draw&&!this.game)this.game=4;var status;switch(this.game){case 1:status='Player 1 wins!';break;case 2:status='Player 2 wins!';break;case 3:status='Player 1 and 2 wins! A draw?';break;case 4:status='It\'s a draw!';break;}
if(this.game){this.setStatus(status);this.boardCover(true);if(this.lastMarble)$('s-'+this.lastMarble).removeClass('last');$('player-2-label').removeClass('current');$('player-1-label').removeClass('current');$('history-link').removeClass('disabled');if(this.gameType==0)$('undo-link').removeClass('disabled');}},checkWinningMarbles:function(x,y,direction){var valid=false;var state=this.boardMatrix[y][x];if(state){switch(direction){case'horizontal':for(var i=1;i<this.options.winLength&&(valid=this.boardMatrix[y][x+i]==state);i++);if(valid)
for(var j=x;j<x+this.options.winLength;j++)
$('s-'+y+j).addClass('win');break;case'vertical':for(var i=1;i<this.options.winLength&&(valid=this.boardMatrix[y+i][x]==state);i++);if(valid)
for(var j=y;j<y+this.options.winLength;j++)
$('s-'+j+x).addClass('win');break;case'l-diagonal':for(var i=1;i<this.options.winLength&&(valid=this.boardMatrix[y+i][x+i]==state);i++);if(valid)
for(var j=y,k=x;j<y+this.options.winLength&&k<x+this.options.winLength;j++,k++)
$('s-'+j+k).addClass('win');break;case'r-diagonal':for(var i=1;i<this.options.winLength&&(valid=this.boardMatrix[y+i][x-i]==state);i++);if(valid)
for(var j=y,k=x;j<y+this.options.winLength&&k>x-this.options.winLength;j++,k--)
$('s-'+j+k).addClass('win');break;}
if(valid){if(state==1)
this.game=(this.game==2)?3:1;else if(state==2)
this.game=(this.game==1)?3:2;}}},setStatus:function(text){var status=$('status');if($defined(text))
status.set('text',text).fade(1);else
status.empty().fade(0);},computerMove:function(){var TIME=1000;this.boardCover(true);if(this.playerType==2){var matrix=this.boardMatrix.flatten().join('');ai_parameters={'m':matrix,'p':this.player,'ai':0,'l':this.computerLevel[this.player-1],'_t':$time()+$random(0,100)};var request=new Request({url:this.options.aiURL,method:'get',data:ai_parameters,onComplete:function(response){var rmove=response.split('');this.cmove[0]=(function(){this.place(rmove[0].toInt(),rmove[1].toInt());if(!this.game)
this.cmove[1]=(function(){this.rotate(rmove[2].toInt(),rmove[3]);}.bind(this)).delay(TIME,rmove);}.bind(this)).delay(TIME,rmove);}.bind(this)}).send();}}});