
/**
 * Chessig - wersja dla stron - sieci web
 * 
 * @param rootUrl
 * @param size
 * @param containerElement
 * @return
 */
function ChessigWeb(rootUrl, containerElement, storage) {
	/**
	 * pamieć podręczna
	 */
	this._storage = storage ? storage : new ChessigCookieStorage();
	/**
	 * Aktualny rozmiar szachownicy, domyslnie 30
	 */
	var size = this._storage.getZoomSize();
	this._size =  size ? size : 30; 
	/**
	 * Element, ktory jest kontenerem gry
	 */
	this._containerElement = containerElement;
	/**
	 * Szachownica, na poczatek pusta
	 */
	this._board = new Board(rootUrl, this._size, "8/8/8/8/8/8/8/8", true);
	/**
	 * Połączenie do serwera
	 */
	this._chessig = new Chessig();
	/**
	 * rozmiary strony
	 */
	this._sizes = new Array(12,20,24,30,36,42,46,50,64); // sa jeszcze: 5,8,10,128
	/**
	 * pokaz ruch z historii
	 * 0 - aktualny stan gry
	 * 1 - jeden ruch do tylu - sytuacja jaka mial przeciwnik, itd
	 */
	this._history = 0;
	/**
	 * przyciski i inne elementy na stronie
	 */
	this._newGameWhiteButton = null;
	this._newGameBlackButton = null
	this._undoButton = null;
	this._levelLowButton = null;
	this._levelAverageButton = null;
	this._levelHighButton = null;
	this._historyBackButton = null;
	this._historyNextButton = null;
	this._actionField = null;
	this._form = null;
	// utworzenie szachownicy i polaczenie zdarzen
	this._bindButtons();
	this._create();
	this._bindEvents();
}

/**
 * Utworzenie szachownicy, i polaczenie zdarzen
 * @return
 */
ChessigWeb.prototype._create = function() {
	this._containerElement.innerHTML = "";
	this._containerElement.appendChild(this._board.create());
	this._board.boardElement.className = "chessig_board";
}
/**
 * Powiazanie zdarzen
 */
ChessigWeb.prototype._bindEvents = function() {
	var oThis = this;
	/**
	 * Utworzono nowego gracza
	 */
	this._chessig.onPlayerCreated = function(c) {
		oThis._storage.setPlayerHashKey(oThis._chessig._playerHashKey);
		oThis._chessig.newGame(true);
	}
	/**
	 * Utworzono nowa gre
	 */
	this._chessig.onNewGame = function(c) {
		oThis._handleRefresh();
	}
	/**
	 * Wymagane jest odswierzenie planszy 
	 */
	this._chessig.onRefresh = function(c) {
		oThis._handleRefresh();
	}
	/**
	 * Cofnieto gre
	 */
	this._chessig.onUndo = function(c) {
		oThis._handleRefresh();
	}
	/**
	 * Wykonano ruch
	 */
	this._chessig.onMakeMove = function(c) {
		oThis._handleRefresh();
	}
	/**
	 * Zmieniono poziom trudnosci
	 */
	this._chessig.onSetLevel = function(c) {
		oThis._handleRefresh();
	}
	
	/**
	 * Gracz klikna na pole na szachownicy
	 */
	this._board.onclick = function(fe) {
		oThis._handleClick(fe);
	}
}

/**
 * Kliknieto na szachownice
 * @param FieldEvent fe
 * @return
 */
ChessigWeb.prototype._handleClick = function(fe) {
	if(this._isShowingHistory()) {
		// gdy kliknelismy w plansze pokazujaca historie 
		// to nic nie robimy lub moze wracamy do aktualnego stanu gry ???
		// to wracamy do aktualnego stanu gry
		// this._handleRefresh();
		return;
	}
	var fieldName = fe.getName();
	if(fieldName==this._actionField.value) {
		// kasowanie ruchu
		fe.setActive(false);
		this._actionField.value = "";
		this._showClickableFields();
	} else {
		if(0==this._actionField.value.length || 2==this._actionField.value.length) {
			// sprawdzamy czy ruch jest mozliwy
			var newMove = this._actionField.value + fieldName;
			if(this._chessig.isPossibleMove(newMove)) {
				// ruch jest mozliwy - zaznaczamy go
				fe.setActive(true);
				this._actionField.value = newMove;
				this._showClickableFields();
				if(newMove.length==4) {
					this._makeMove(newMove);
				}
			}
		}
	}
	
}

/**
 * Odsiezamy sytuacje
 * @return
 */
ChessigWeb.prototype._handleRefresh = function() {
	this._history = 0;
	this._storage.setGameId(this._chessig._gameId);
	this._board.setWhiteOnBottom(this._chessig._isSpectator || this._chessig._isWhite);
	this._board.updateEpd(this._chessig._epd);
	this._actionField.value = "";
	this._showClickableFields();
	this._showMoves();
	this._showLevel();
	this._containerElement.className = "";
	this._showHistoryButtons();
	this._showUndoButton();
}

/**
 * Pokazanie na szachownicy, ktore pola mozemy kliknac
 */
ChessigWeb.prototype._showClickableFields = function() {
	this._board.setClassForAllFields("");
	if(this._chessig._isMyTurn) {
		var moveName = this._actionField.value.toLowerCase();
		if(0==moveName.length||2==moveName.length) {
			var moves = this._chessig.findAvalibleMoves(new RegExp("^"+moveName));
			var fields = new Array();
			for ( var i in moves ) {
				var move = moves[i];
				var field = move.charAt(0+moveName.length)+move.charAt(1+moveName.length);
				fields.push(field);
			}
			this._board.setClassForFields(fields, "chessig_clickable");
		}
	}		
}
/**
 * Pokazania na szachownicy dozwolonych ruchow
 */
ChessigWeb.prototype._showMoves = function() {
	this._board.setDeactiveForAll();
	this._board.showMove(this._chessig._lastMove);
	this._board.showMove(this._actionField.value.toLowerCase());
}
/**
 * Pokaz poziom trudnosci
 */
ChessigWeb.prototype._showLevel = function() {
	var d = this._chessig._depth;
	this._levelLowButton.className     = d == 3 ? "chessig_currentLevel" : ""; 
	this._levelAverageButton.className = d == 4 ? "chessig_currentLevel" : "";
	this._levelHighButton.className    = d == 5 ? "chessig_currentLevel" : "";
}


/**
 * Wykonaj ruch, o ile to mozliwe
 * @return
 */
ChessigWeb.prototype._makeMove = function(moveName) {
	// czy podano przynajmniej 4 znaki
	if(moveName.length<4) {
		return;
	}
	moveName = moveName.toLowerCase();
	var moves = this._chessig.findAvalibleMoves(new RegExp("^"+moveName.toLowerCase()));
	if(moves.length==1) {
		this._chessig.makeMove(moveName);
	} else if ( moves.length > 1 ) {
		// mamy piona na linie przemian, zamieniamy w hetmana
		this._chessig.makeMove(moveName+"q");
	}
}



 

/**
 * Powiazanie przyciskow
 */
ChessigWeb.prototype._bindButtons = function() {
	// zebranie elementow strony
	this._newGameWhiteButton = document.getElementById("chessig_newGameWhiteButton");
	this._newGameBlackButton = document.getElementById("chessig_newGameBlackButton");
	this._undoButton         = document.getElementById("chessig_undoButton");
	this._levelLowButton     = document.getElementById("chessig_levelLowButton");
	this._levelAverageButton = document.getElementById("chessig_levelAverageButton");
	this._levelHighButton    = document.getElementById("chessig_levelHighButton");
	this._historyBackButton  = document.getElementById("chessig_historyBackButton");
	this._historyNextButton  = document.getElementById("chessig_historyNextButton");
	this._zoomInButton       = document.getElementById("chessig_zoomInButton");
	this._zoomOutButton      = document.getElementById("chessig_zoomOutButton");
	this._actionField        = document.getElementById("chessig_actionField");
	this._form               = document.getElementById("chessig_form");
	// podpiecie akcji
	var oThis = this;
	this._newGameWhiteButton.onclick = function() { oThis._chessig.newGame(true); };
	this._newGameBlackButton.onclick = function() { oThis._chessig.newGame(false); };
	this._undoButton.onclick         = function() { oThis._chessig.undo(); };
	this._levelLowButton.onclick     = function() { oThis._chessig.setLevel(3); };
	this._levelAverageButton.onclick = function() { oThis._chessig.setLevel(4); };
	this._levelHighButton.onclick    = function() { oThis._chessig.setLevel(5); };
	this._historyBackButton.onclick  = function() { oThis._historyBack(); };
	this._historyNextButton.onclick  = function() { oThis._historyNext(); };
	this._zoomInButton.onclick       = function() { oThis.zoomIn(); };
	this._zoomOutButton.onclick      = function() { oThis.zoomOut(); };
	this._actionField.onkeyup        = function() {	
		oThis._showClickableFields(); 
		oThis._showMoves();
	}
	this._form.onsubmit              = function() { 
		oThis._makeMove(oThis._actionField.value);
		return false;
	};
	// czyszcenie pola, gdy cos tam bylo wpisane
	this._actionField.value = "";
}
	


/**
 * Uruchomienie zabawki
 * @return
 */
ChessigWeb.prototype.run = function() {
	var phk = this._storage.getPlayerHashKey();
	if(phk) {
		this._chessig._playerHashKey = phk;
		var gameId = this._storage.getGameId();
		if(gameId) {
			this._chessig._gameId = gameId;
			this._chessig.refresh();
		} else {
			// XXX to trzeba przemyslec
			this._chessig.newGame(true);
		}
	} else {
		this._chessig.createPlayer();
	}
}

/**
 * Ustalenie rozmiaru szachownicy
 * @param size
 * @return
 */
ChessigWeb.prototype.setSize = function(size) {
	var inArray = false;
	for( var i=0; i < this._sizes.length; i++ ) {
		if(this._sizes[i]==size) {
			inArray=true;
			break;
		}
	}
	if(!inArray) {
		return;
	}
		
	this._size = size;
	this._board.setSize(size);
	this._showElement(this._zoomOutButton, size != this._sizes[0]);
	this._showElement(this._zoomInButton,  size != this._sizes[this._sizes.length-1]);
	this._storage.setZoomSize(size);
}

/**
 * Powiekszneie szachownicy
 * @return
 */
ChessigWeb.prototype.zoomIn = function() {
	for( var i=0; i < this._sizes.length - 1; i++ ) {
		if(this._sizes[i] == this._size) {
			this.setSize(this._sizes[i+1]);
			return;
		}
	}
}

/**
 * Pomniejszenie szachownicy
 * @return
 */
ChessigWeb.prototype.zoomOut = function() {
	for( var i=1; i < this._sizes.length; i++ ) {
		if(this._sizes[i] == this._size) {
			this.setSize(this._sizes[i-1]);
			return;
		}
	}
}


/**
 * Pokaz lub ukryj element, z zachowaniem jego pozycji na ekranie
 * @param element
 * @param show
 * @return
 */
ChessigWeb.prototype._showElement = function(element, show) {
	element.style.visibility = show ? "visible" : "hidden";
}

/**
 * Czy to co teraz pokazujemy na szachownicy to historia
 * czy aktualna pozycja w grze
 *  
 * @param element
 * @param show
 * @return
 */
ChessigWeb.prototype._isShowingHistory= function() {
	return this._history != 0;
}

/**
 * Pokaz poprzedni ruch w hisorii, o ile to mozliwe
 * @return
 */
ChessigWeb.prototype._historyBack= function() {
	if( this._history <= this._chessig._history.length ) {
		this._history++;
	}
	this._showHistory();
}
/**
 * Pokaz nastepny ruch w historii, o ile to mozliwe
 * @return
 */
ChessigWeb.prototype._historyNext= function() {
	if( this._history > 0 ) {
		this._history--;
	}
	this._showHistory();
}
/**
 * Pokazanie historii 
 */
ChessigWeb.prototype._showHistory = function() {
	if(this._history==0) {
		// gdy jestesmy na aktualnej pozycji w history
		this._handleRefresh();
		return;
	}
	this._containerElement.className = "chessig_history";
	this._board.updateEpd(this._chessig._history[ this._history - 1]);
	this._board.setClassForAllFields("");
	this._showHistoryButtons();
	this._showUndoButton();
}
/**
 * Pokaz lub ukryj przycisk odpowiedzialne za podglad historii
 */
ChessigWeb.prototype._showHistoryButtons = function() {
	this._historyNextButton.style.visibility = this._history == 0 ? "hidden" : "visible";
	this._historyBackButton.style.visibility = this._history == this._chessig._history.length ? "hidden" : "visible";
	this._actionField.style.visibility       = this._history != 0 ? "hidden" : "visible"; 
}
/**
 * Czy mamy pokazywac przycisk undo
 */
ChessigWeb.prototype._showUndoButton = function() {
	this._undoButton.style.visibility = this._chessig._history.length < 2 ? "hidden" : "visible";
}

