// (C)2008 Julio Di Egidio
// http://julio.diegidio.name
// mailto:julio@diegidio.name

var jde_ge_noValue=-1;var jde_ge_gameWho={me:"ME",you:"YO"};var jde_ge_gameAction={newGame:"NEWG",restart:"REST",move:"MOVE",undo:"UNDO",suggest:"SUGG",startAutoplay:"STAA",stopAutoplay:"STOA"};jde_ge_gameAction.parse=function(gameAction){if(!(gameAction===this.newGame||gameAction===this.restart||gameAction===this.move||gameAction===this.undo||gameAction===this.suggest||gameAction===this.startAutoplay||gameAction===this.stopAutoplay)){return jde_ge_noValue;}return gameAction;};function jde_ge_Model(board){var _board=board;var _sendEventRef,_updateFuncName;this.init=function(sendEventRef,updateFuncName){_sendEventRef=sendEventRef;_updateFuncName=updateFuncName;};this.reset=function(){_board.reset();_sendEventRef(_updateFuncName+"()");};this.move=function(boardCoord){var boardState=_board.move(boardCoord);if(boardState===jde_ge_noValue){return jde_ge_noValue;}_sendEventRef(_updateFuncName+"()");return boardState;};this.undo=function(){var boardState=_board.undo();if(boardState===jde_ge_noValue){return jde_ge_noValue;}_sendEventRef(_updateFuncName+"()");return boardState;};this.getBoardCells=function(){return _board.getCells();};this.getBoardCell=function(boardCoord){return _board.getCell(boardCoord);};this.getBoardState=function(){return _board.getState();};this.getLastMove=function(){return _board.getLastMove();};this.getBoardWinCoords=function(){return _board.getWinCoords();};}function jde_ge_APlayer(aPlayer){var _aPlayer=aPlayer;var _sendEventRef,_updateFuncName;this.init=function(sendEventRef,updateFuncName){_sendEventRef=sendEventRef;_updateFuncName=updateFuncName;};this.reset=function(){_aPlayer.reset();};this.getNextMove=function(strategy){return _aPlayer.getNextMove(strategy);};this.getStrategy=function(){return _aPlayer.getStrategy();};this.setStrategy=function(strategy){strategy=_aPlayer.setStrategy(strategy);if(strategy===jde_ge_noValue){return jde_ge_noValue;}return strategy;};this.getFuzzyThreshold=function(){return _aPlayer.getFuzzyThreshold();};this.setFuzzyThreshold=function(threshold){threshold=_aPlayer.setFuzzyThreshold(threshold);if(threshold===jde_ge_noValue){return jde_ge_noValue;}return threshold;};}function jde_ge_Controller(model,aPlayer,gx_BoardCoord,gx_boardState,gx_aStrategy){var _model=model,_aPlayer=aPlayer;var _gx_BoardCoord=gx_BoardCoord,_gx_boardState=gx_boardState,_gx_aStrategy=gx_aStrategy;var _selfName,_notifyFuncName,_sendEventRef,_clearEventRef,_aiDelay,_autoDelay,_fastDelay,_updateFuncName,_updateFuncNameExt;var _fastAuto,_autoStrategy;var _startWho=jde_ge_noValue,_gameWho=jde_ge_noValue;var _score_all,_score_me,_score_you,_score_draw;var _mtx_busy,_mtx_auto;var that=this;function resetScores(){_score_all=0;_score_me=0;_score_you=0;_score_draw=0;}function incScore(dir){var inc=dir<0?-1:1;var boardState=_model.getBoardState();if(_gx_boardState.isWin(boardState)){_score_all+=inc;if(_gameWho===jde_ge_gameWho.me){_score_you+=inc;}else{_score_me+=inc;}}else if(_gx_boardState.isDraw(boardState)){_score_all+=inc;_score_draw+=inc;}}function clearIntMtxs(){_mtx_busy=null;_mtx_auto=null;}function sendIntEvent(funcName,delay,isAuto){if(_mtx_busy!==null){return;}_mtx_busy=_sendEventRef(_selfName+"."+funcName+"()",delay);if(isAuto===true){_mtx_auto=true;}}function clearIntEvent(){if(_mtx_busy!==null){_clearEventRef(_mtx_busy);clearIntMtxs();}}this.def_startWho=jde_ge_gameWho.you;this.def_fastAuto=true;this.init=function(selfName,notifyFuncName,sendEventRef,clearEventRef,aiDelay,autoDelay,fastDelay,updateFuncName_M,updateFuncName_A,updateFuncName_C,updateFuncName_E){_model.init(sendEventRef,updateFuncName_M);_aPlayer.init(sendEventRef,updateFuncName_A);_selfName=selfName;_notifyFuncName=notifyFuncName;_sendEventRef=sendEventRef;_clearEventRef=clearEventRef;_aiDelay=aiDelay;_autoDelay=autoDelay;_fastDelay=fastDelay;_updateFuncName=updateFuncName_C;_updateFuncNameExt=updateFuncName_E;clearIntMtxs();that.reset();};this.reset=function(){clearIntEvent();_model.reset();_aPlayer.reset();_fastAuto=that.def_fastAuto;_autoStrategy=_gx_aStrategy.getDefault();_startWho=that.def_startWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;_gameWho=jde_ge_noValue;resetScores();_sendEventRef(_updateFuncName+"()"+"; "+_updateFuncNameExt+"()");};this.newGame=function(){if(that.getIsActionDisabled(jde_ge_gameAction.newGame)){return jde_ge_noValue;}clearIntEvent();_model.reset();_startWho=_startWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;_gameWho=_startWho;if(_gameWho===jde_ge_gameWho.me){sendIntEvent("_moveAPlayer",_aiDelay);}_sendEventRef(_updateFuncName+"()");};this.restart=function(){if(that.getIsActionDisabled(jde_ge_gameAction.restart)){return jde_ge_noValue;}clearIntEvent();if(that.getIsEOG()){incScore(-1);}_model.reset();_gameWho=_startWho;if(_gameWho===jde_ge_gameWho.me){sendIntEvent("_moveAPlayer",_aiDelay);}_sendEventRef(_updateFuncName+"()");};this.move=function(boardCoord){if(that.getIsActionDisabled(jde_ge_gameAction.move)){return jde_ge_noValue;}clearIntEvent();var boardState=_model.move(boardCoord);if(boardState===jde_ge_noValue){return jde_ge_noValue;}_gameWho=_gameWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;if(that.getIsEOG()){incScore();}else{sendIntEvent("_moveAPlayer",_aiDelay);}_sendEventRef(_updateFuncName+"()");};this._moveAPlayer=function(){clearIntMtxs();var boardCoord=_aPlayer.getNextMove();if(boardCoord===jde_ge_noValue){return jde_ge_noValue;}var boardState=_model.move(boardCoord);if(boardState===jde_ge_noValue){return jde_ge_noValue;}_gameWho=_gameWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;if(that.getIsEOG()){incScore();}_sendEventRef(_updateFuncName+"()");};this.undo=function(){if(that.getIsActionDisabled(jde_ge_gameAction.undo)){return jde_ge_noValue;}clearIntEvent();if(that.getIsEOG()){incScore(-1);}var boardState=_model.undo();if(boardState===jde_ge_noValue){return jde_ge_noValue;}_gameWho=_gameWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;if(that.getIsBOG()){sendIntEvent("_moveAPlayer",_aiDelay);}else if(_gameWho===jde_ge_gameWho.me){that._undoPlayer();}_sendEventRef(_updateFuncName+"()");};this._undoPlayer=function(){clearIntMtxs();var boardState=_model.undo();if(boardState===jde_ge_noValue){return jde_ge_noValue;}_gameWho=_gameWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;};this.suggest=function(){if(that.getIsActionDisabled(jde_ge_gameAction.suggest)){return jde_ge_noValue;}clearIntEvent();sendIntEvent("_suggest",_aiDelay);_sendEventRef(_updateFuncName+"()");};this._suggest=function(){clearIntMtxs();var boardCoord=_aPlayer.getNextMove();if(boardCoord===jde_ge_noValue){return jde_ge_noValue;}_sendEventRef(_notifyFuncName+"("+_gx_BoardCoord.getBuilderName(boardCoord)+")");_sendEventRef(_updateFuncName+"()");};this.startAutoplay=function(){if(that.getIsActionDisabled(jde_ge_gameAction.startAutoplay)){return jde_ge_noValue;}clearIntEvent();if(that.getIsEOG()){_model.reset();_startWho=_startWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;_gameWho=_startWho;}if(!_fastAuto){sendIntEvent("_autoplay",_autoDelay,true);_sendEventRef(_updateFuncName+"()");}else{that._autoplay();}};this._autoplay=function(){clearIntMtxs();if(that.getIsEOG()){_model.reset();_startWho=_startWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;_gameWho=_startWho;}else{var boardCoord=_aPlayer.getNextMove(_gameWho===jde_ge_gameWho.me?undefined:_autoStrategy);if(boardCoord===jde_ge_noValue){return jde_ge_noValue;}var boardState=_model.move(boardCoord);if(boardState===jde_ge_noValue){return jde_ge_noValue;}_gameWho=_gameWho===jde_ge_gameWho.me?jde_ge_gameWho.you:jde_ge_gameWho.me;if(that.getIsEOG()){incScore();}}if(!_fastAuto||that.getIsEOG()){sendIntEvent("_autoplay",_fastAuto?_fastDelay:_autoDelay,true);_sendEventRef(_updateFuncName+"()");}else{that._autoplay();}};this.stopAutoplay=function(){if(that.getIsActionDisabled(jde_ge_gameAction.stopAutoplay)){return jde_ge_noValue;}clearIntEvent();if(!that.getIsEOG()){if(_gameWho===jde_ge_gameWho.me){sendIntEvent("_moveAPlayer",_aiDelay);}}_sendEventRef(_updateFuncName+"()");};this.getIsActionDisabled=function(gameAction){if(gameAction===jde_ge_gameAction.newGame){return that.getIsAuto();}if(gameAction===jde_ge_gameAction.restart){return that.getIsBOG()||that.getIsAuto();}if(gameAction===jde_ge_gameAction.move){return that.getIsEOG()||that.getIsBusy()||that.getIsAuto();}if(gameAction===jde_ge_gameAction.undo){return that.getIsBOG()||that.getIsAuto();}if(gameAction===jde_ge_gameAction.suggest){return that.getIsEOG()||that.getIsBusy()||that.getIsAuto();}if(gameAction===jde_ge_gameAction.startAutoplay){return that.getIsAuto();}if(gameAction===jde_ge_gameAction.stopAutoplay){return!that.getIsAuto();}return true;};this.getIsHidle=function(){if(_startWho===jde_ge_noValue){return false;}return _gameWho===jde_ge_noValue;};this.getIsBOG=function(){if(_gameWho===jde_ge_noValue){return true;}var lastMove=_model.getLastMove();return lastMove===jde_ge_noValue;};this.getIsEOG=function(){if(_gameWho===jde_ge_noValue){return true;}var boardState=_model.getBoardState();return!_gx_boardState.isMove(boardState);};this.getIsBusy=function(){if(_gameWho===jde_ge_noValue){return false;}return _mtx_busy!==null;};this.getIsAuto=function(){if(_gameWho===jde_ge_noValue){return false;}return _mtx_auto!==null;};this.getStartWho=function(){return _startWho;};this.getGameWho=function(){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return _gameWho;};this.getScoreAll=function(){if(_gameWho===jde_ge_noValue){return jde_ge_noValue;}return _score_all;};this.getScoreMe=function(){if(_gameWho===jde_ge_noValue){return jde_ge_noValue;}return _score_me;};this.getScoreYou=function(){if(_gameWho===jde_ge_noValue){return jde_ge_noValue;}return _score_you;};this.getScoreDraw=function(){if(_gameWho===jde_ge_noValue){return jde_ge_noValue;}return _score_draw;};this.getFastAuto=function(){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return _fastAuto;};this.setFastAuto=function(fastAuto){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return(_fastAuto=!!fastAuto);};this.getAiStrategy=function(){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return _aPlayer.getStrategy();};this.setAiStrategy=function(strategy){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return _aPlayer.setStrategy(strategy);};this.getAutoStrategy=function(){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return _autoStrategy;};this.setAutoStrategy=function(strategy){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}strategy=_gx_aStrategy.parse(strategy);if(strategy===jde_ge_noValue){return jde_ge_noValue;}return(_autoStrategy=strategy);};this.getFuzzyThreshold=function(){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return _aPlayer.getFuzzyThreshold();};this.setFuzzyThreshold=function(threshold){if(_startWho===jde_ge_noValue){return jde_ge_noValue;}return _aPlayer.setFuzzyThreshold(threshold);};}