// JavaScript Document


var number_rows = new Array();
var eraser_on= false;
var current_number;
var lang = "en";

var gDoneButton;
var gInfoButton;

var gameWidth = 9;
var gameHeight = 9;
var elementsWidth = 9;
var elementsHeight = 9;

// clock
var cSec = 0;
var cMin = 0
var clockInterval;

// counts
var joker_count = 0;
var check_count = 0;

//advanced
var lang = "en";

function changeHeight(h) {
	elementsHeight = h.value;
	newGame();
}

function changeWidth(w) {
	elementsWidth = w.value;
	newGame();
}


function newGame() {
	var numbers = document.getElementById("numbers_container");
	numbers.innerHTML = createNumbers();
	
	var stage = document.getElementById("stage_container");
	stage.innerHTML = createStage();
	
	cSec = 0;
	cMin = 0;
	joker_count = 0;
	check_count = 0;
	clearInterval( clockInterval );
	clockInterval = setInterval("clockTik()", 1000);
};

function changeStyle(style) {
	document.getElementById('game_style').href = 'game_' + style.value + '.css';	
}

function clockTik() {
	
	if( cMin == 60 ) {
		clearInterval( clockInterval );	
	} else {
		var csMin = cMin < 10 ? "0" + cMin : cMin;
		var csSec = cSec < 10 ? "0" + cSec : cSec;
		document.getElementById("clock").innerHTML = csMin + ":" + csSec;
		
		cSec++;
		if( cSec == 60 ){
			cSec = 0;
			cMin++;
		}
	}
}

function createStage() {
	number_rows = new Array();
	
	var debug_s ="";
	for( var i = 0; i < elementsHeight; i++ ) {
		var row = new Array();
		if( i == 0 ) {
			for( var j = 0; j < elementsWidth; j++ ) { row.push( 0 ); }
		} else {

			do{
				var max;
				var offset;
				if ( row.length == 0  ) {
					var first_value = 1;
					for( var j = 0; j < number_rows[ number_rows.length - 1].length; j++ ){
						if( number_rows[ number_rows.length - 1 ][j] > 0 ) {
							first_value = j;
							break;
						}
					}
					
					max = first_value + 1 > Math.round( elementsWidth / 2 ) - 1 ? Math.round( elementsWidth / 2 ) - 1 : first_value + 1;
					min = max - 1 == 0 ? 1 : max - 1;
					offset = getRandom( min, max );
					/*
					if( number_rows[ number_rows.length - 1 ][offset] == 0 && offset > 3 ) {
						offset -= 1;
					}*/
					
				} else {
					offset = getRandom( 1, 2 );
					//offset = 1;
				}
				
				if( number_rows.length >= elementsWidth - 3 ) {
					offset = 1;
				}
				
				var empty_added = false;
				for( var j = 0; j < offset; j++ ) {
					if( number_rows.length == 2 && number_rows[ number_rows.length - 1 ][row.length + 1] <= 0 ) {
						break;	
					} else {
						row.push( 0 );
						empty_added = true;
					}
				}
				
				if( row.length == 0 ) { row.push( 0 ) };
				
				var snippetMax = elementsWidth - row.length > 2 ? 2 : elementsWidth - row.length;
				var min = 1;
				/*if( number_rows.length > 1 && number_rows[ number_rows.length - 1 ][row.length+1] <= 0 ) {
					min = 1;
				}*/
				
				var snippetLength = getRandom( min, snippetMax  );
				
				// prevent closed cells
				if( number_rows.length > 1 ) {
					for( j = snippetLength; j < elementsWidth - row.length; j++ ) {
						if( number_rows[ number_rows.length - 1 ][snippetLength + row.length - 2] <= 0 && 
							number_rows[ number_rows.length - 1 ][snippetLength + row.length - 1] <= 0 ) {
							
							snippetLength += 1;
						} else if( 	number_rows[ number_rows.length - 1 ][snippetLength + row.length - 1] <= 0 ||
									number_rows[ number_rows.length - 1 ][snippetLength + row.length ] <= 0 ) {
							
							snippetLength += 1;
						} else {
							break;	
						}
					}
				}
				
				snippetLength = elementsWidth - row.length - snippetLength == 1 ? snippetLength + 1: snippetLength;
				
				var not_to_use_row = new Array();
				if ( empty_added == false ) {
					for( var j = row.length - 1; j >= 0;j-- ) { 
						if ( row[j] <= 0 ) {
							break;
						}
						not_to_use_row.push( row[j] ) ;
					}
				}
				
				for( var j = 0; j < snippetLength; j++ ) {
					var not_to_use = new Array();
					var not_to_use_column = new Array();
					if( number_rows.length > 0 ) {
						for( var k = number_rows.length - 1; k >= 0; k--){ 
							if ( number_rows[k][ row.length ] <= 0 ) {
								break;	
							} else {
								not_to_use_column.push( number_rows[k][ row.length ] );
							}
						}
					}
					
					not_to_use = not_to_use_column.concat( not_to_use_row );
					
					var newSnippet = getRandom( 1, 9, not_to_use );
					if( not_to_use_column.length > getRandom( 2, 4 ) && row.length - 2 != 0 ) {
						 if( row.length < elementsWidth && number_rows.length <= elementsWidth - 3 ) { row.push( 0 ) }
						 else { break; }
					} else if ( not_to_use_column.length > getRandom( Math.round( elementsWidth / 2 ) - 1, Math.round( elementsWidth / 2 ) + 1) ) {
						 //row[ row.length - 1 ] = 0;
						 if( row.length < elementsWidth && number_rows.length <= elementsWidth - 3) { row.push( 0 ) }
						 else { break; }
					} else {
						not_to_use_row.push( newSnippet );
						if( row.length < elementsWidth ) { row.push( newSnippet ); }
						else { break; }
					}
				}
				
			} while ( row.length < elementsWidth );
		}
		
		
		number_rows.push(row);
	
		var row_s = "";
		for( var j = 0; j < number_rows[ number_rows.length - 1 ].length; j++ ) {
			if( number_rows[ number_rows.length - 1 ][j] < 0 ) { number_rows[ number_rows.length - 1 ][j] = 0; }
			row_s += number_rows[ number_rows.length - 1 ][j];
		}
		debug_s += row_s + "<br />";
		//debug(debug_s);
	}
	
	if( elementsWidth < gameWidth || elementsHeight < gameHeight) {
		for( var i = 1; i < gameHeight; i++ ) {
			if( i < number_rows.length ) {
				for( var j = elementsWidth; j < gameWidth; j++ ){
					if( j == elementsWidth ) {
						number_rows[i].push( 0 );
					} else {
						number_rows[i].push( -1 );	
					}
				}
			} else if ( i == elementsHeight ) { 
				var dummy = new Array();
				for( var j = 0; j < gameWidth; j++ ){
					if( j < elementsWidth ) {
						dummy.push( 0 );
					} else {
						dummy.push( -1 );
					}
				}
				
				number_rows.push( dummy );
			} else {
				var dummy = new Array();
				for( var j = 0; j < gameWidth; j++ ){
					dummy.push( -1 );
				}
				number_rows.push( dummy );
			}
		}
	}
	
	var table = "<table id=\"stage\" width=\"360\" height=\"360\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";
	
	for( var i = 0; i < number_rows.length; i++ ) {
		var horizontal	= new Array();
		var horizontal_count = new Array();
		var index 		= 0;
		var sum 		= 0;
		var prev_index = 0;
		for	( var j = 0; j < number_rows[i].length; j++ ) {
			if( number_rows[i][j] > 0 ){
				sum += number_rows[i][j];
			} else {
				if( sum > 0 ) {
					horizontal[index] = sum;
					horizontal_count[index] = j - index - 1;
					prev_index = index;
				}
				
				index = j;
				sum   = 0;
			}
		}
		if( sum > 0 ) {
			horizontal[index] = sum;	
			horizontal_count[index] = number_rows[i].length - index - 1;
		}
		
		var row = "<tr>";
		for	( var j = 0; j < number_rows[i].length; j++ ) {
			var vertical = new Array();
			var vertical_count = new Array();
			var v_index  = 0;
			var v_sum    = 0;
			var prev_index;
			if( number_rows[i][j] <= 0 ) {
				for( var k = 0; k < number_rows.length; k++ ) {
					if( number_rows[k][j] > 0 ) {
						v_sum += number_rows[k][j];
					} else {
						if( v_sum > 0 ) {
							vertical[v_index] = v_sum;	
							vertical_count[v_index] = k - v_index - 1;
						}
						prev_index = v_index;
						v_index = k;
						v_sum   = 0;
					} 
				}
			}
			if( v_sum > 0 ) {
				vertical[v_index] = v_sum;	
				vertical_count[v_index] = number_rows.length - v_index - 1;
			}
			
	
			if( horizontal[j] > 0 || vertical[i]) {
				var v_value = vertical[i] > 0 ? vertical[i] : "";
				var h_value = horizontal[j] > 0 ? horizontal[j] : "";
				
				row += 	"<td>" + 
							"<div class=\"sum_place\" id=\""+ i + "-" + j +"\">" + 
								"<div class=\"sum_top\"><a href=\"javascript:showCombos(" + h_value +"," + horizontal_count[j] +", 1,'')\;\">" +  h_value + "</a></div>" + 
								"<div class=\"sum_bottom\"><a href=\"javascript:showCombos(" + v_value +"," + vertical_count[i] +", 1,'')\;\">" + v_value + "</a></div>" + 
							"</div>" + 
						"</td>";
						
			} else if( number_rows[i][j] > 0 ) {
				row += "<td><div class=\"place\" onClick=\"javascript:getNumber(this);\" id=\"" + i + "-" + j + "\">" + /*number_rows[i][j] + */"</div></td>";	
			} else  if( number_rows[i][j] == 0 )  {
				row += "<td><div class=\"duck_place\">" /*+ number_rows[i][j] */+ "</div></td>";	
			} else {
				row += "<td><div class=\"empty_place\">" /*+ number_rows[i][j] */+ "</div></td>";				
			}
		}
		table += row + "</td>";
	}
	
	return table;
}

function getNumber (obj) {
	if( current_number > 0 ) {
		obj.parentNode.innerHTML = "<div class=\"number\" onClick=\"javascript:deleteThis(this);\" id=\"" +obj.id + "\">" + current_number + "</div>";
	}
}

function deleteThis(element){
	element.parentNode.innerHTML = "<div class=\"place\" onClick=\"javascript:getNumber(this);\" id=\"" +element.id + "\">" + /*number_rows[i][j] + */"</div>";		
}

function giveMeAHint() {
	var stage_table = document.getElementById("stage");
	
	var divs = document.getElementsByClassName("place", stage_table);	
	
	var theHint = -1;
	var randDiv = getRandom( 0, divs.length );
	var numberIndex = divs[randDiv].id.split("-");
	theHint = number_rows[ numberIndex[0] ][ numberIndex[1] ];
		
	divs[randDiv].parentNode.innerHTML = "<div class=\"number\" onClick=\"javascript:deleteThis(this);\" id=\"" +divs[randDiv].id + "\">" + theHint + "</div>";
	joker_count++;
}


	/*
	// old check
	} else {
	// standard check
		for( var i = 0; i < numbers.length; i++ ) {
			var numberIndex = numbers[i].id.split("-");
			if( number_rows[ numberIndex[0] ][ numberIndex[1] ] != numbers[i].innerHTML ) {
				numbers[i].className = "wrong";
			}
		}
	}
	*/

function check(sums) {
	var duplicates = new Array();
	
	// prepare check_result
	var check_h = new Array();
	for( var i=0; i < gameHeight; i++ ){
		check_h[i] = new Array();
	}
	
	var check_v = new Array();
	for( var i=0; i < gameHeight; i++ ){
		check_v[i] = new Array();
	}

	var duplicates = new Array();
	for( var i=0; i < gameHeight; i++ ){
		duplicates[i] = new Array();
	}

	var stage_table = document.getElementById("stage");
	// clean up old wrong divs
	var wrongs = document.getElementsByClassName("wrong", stage_table);	
	for( var i = 0; i < wrongs.length; i++ ) {
		wrongs[i].className = "number";	
	}
	
	var sums = document.getElementsByClassName("sum_place", stage_table);
	
		for( var i = 0; i < sums.length; i++ ) {
			var sumIndex         = sums[i].id.split("-"); // 0 = row, 1 = column
			var found_end        = false;
			var j                = parseInt( sumIndex[1] ) + 1;
			var current_sum      = 0;
			var solved_sum       = 0;
			var elements_count   = 0;
			var horizontal_numbers = new Array(); // to check vertical duplicates
			var not_complete     = false;
			var k = j;
			
			do {
				if( number_rows[ sumIndex[0] ][k]  <= 0 ) {
					found_end = true; 	
				} else {
					var numberDiv = document.getElementById(sumIndex[0] + "-" + k );
					if( numberDiv != null && numberDiv.className == "place" ){
						not_complete = true;
						break;
					}
				}
				
				k++;
			} while( found_end == false && k < gameWidth );
			
			// check sums
			
				found_end = false;
				do {
					if( number_rows[ sumIndex[0] ][j]  <= 0 ) {
						found_end = true; 	
					} else {
						current_sum += number_rows[ sumIndex[0] ][ j ];
						var numberDiv = document.getElementById(sumIndex[0] + "-" + j );
						
						if( numberDiv != null && parseInt( document.getElementById(sumIndex[0] + "-" + j ).innerHTML ) > 0  ) {
							var numberValue = parseInt( document.getElementById(sumIndex[0] + "-" + j ).innerHTML );						
							solved_sum += numberValue;
							
							if( horizontal_numbers[ numberValue ] == null ) {
								horizontal_numbers[ numberValue ] = sumIndex[0] + "-" + j;
							} else {
								var duplicateIndex = horizontal_numbers[ numberValue ].split("-");
								duplicates[duplicateIndex[0]][duplicateIndex[1]] = true;
								duplicates[sumIndex[0]][j] = true;
							}
						}
					}
					
					j++;
				} while( found_end == false && j < gameWidth );
				
				if( not_complete == false ) {
					j = gameWidth == j && found_end != true ? j : j - 1; 
					var status = true;
					if( current_sum != solved_sum ) {
						status = false;
					} 
					
					for( var k = parseInt( sumIndex[1] ) + 1; k < j; k	++ ) {
						if( document.getElementById( sumIndex[0] + "-" + k ) != null &&
								document.getElementById( sumIndex[0] + "-" + k ).className == "number" ) {
							check_h[sumIndex[0]][k] = status;
						}
					}
				}
		}

		// Vertical check
		for( var i = 0; i < sums.length; i++ ) {
			var sumIndex         = sums[i].id.split("-"); // 0 = row, 1 = column
			var found_end        = false;
			var j                = parseInt( sumIndex[0] ) + 1;
			var current_sum      = 0;
			var solved_sum       = 0;
			var elements_count   = 0;
			var vertical_numbers = new Array(); // to check vertical duplicates
			var k = j;
			var not_complete     = false;
			
			do {
				if( k == gameHeight || number_rows[ k ][ sumIndex[1] ] <= 0 ) {
					found_end = true; 
					if( k == j ) { not_complete = true };
					
				} else {
					var numberDiv = document.getElementById( k + "-" + sumIndex[1] );
					if( numberDiv != null && numberDiv.className == "place" ){
						not_complete = true;
						break;
					}
				}
				
				k++;
			} while( found_end == false && k < gameHeight );
			
			
				found_end = false;
				do {
					if( j == gameHeight || number_rows[ j ][ sumIndex[1] ] <= 0 ) {
						found_end = true; 	
					} else {
						current_sum += number_rows[ j ][ sumIndex[1] ];
						var numberDiv = document.getElementById( j + "-" + sumIndex[1] );
				
						if( numberDiv != null && parseInt( document.getElementById( j + "-" + sumIndex[1] ).innerHTML ) > 0  ) {
							var numberValue = parseInt( document.getElementById( j + "-" + sumIndex[1] ).innerHTML );		
							solved_sum += numberValue;
							
							if( vertical_numbers[ numberValue ] == null ) {
								vertical_numbers[ numberValue ] = j + "-" + sumIndex[1];
							} else {
								var duplicateIndex = vertical_numbers[ numberValue ].split("-");
								duplicates[duplicateIndex[0]][duplicateIndex[1]] = true;
								duplicates[j][sumIndex[1]] = true;
							}
						}
					}
					
					j++;
				} while( found_end == false && j < gameHeight );
				
				if( not_complete == false ) {
					j = gameHeight == j && found_end != true ? j : j - 1; 
					var status = true;
					if( current_sum != solved_sum ) {
						status = false	
					} 
					
					for( var k = parseInt( sumIndex[0] ) + 1; k < j; k	++ ) {
						if( document.getElementById( k + "-" + sumIndex[1] ) != null ) {
							if ( document.getElementById( k + "-" + sumIndex[1] ).className == "number" ) {
								check_v[k][sumIndex[1]] = status;
							}
						}
					}
				}
		}
		
		
		for( var i=0; i < gameHeight; i++ ){
			for( var j=0; j < gameWidth; j++ ){	
				if( document.getElementById( i + "-" + j ) != null && document.getElementById( i + "-" + j ).className == "number" ) {
					if( check_v[i][j] == true || check_h[i][j] == true  ) { 
						document.getElementById( i + "-" + j ).className = "number";
					} else if( check_v[i][j] == false || check_h[i][j] == false  ) {
						document.getElementById( i + "-" + j ).className = "wrong";				
					}
					
					if( duplicates[i][j] == true ){
						document.getElementById( i + "-" + j ).className = "wrong";	
					}
					
				}
			}
		}
		
		var wrongs = document.getElementsByClassName("wrong", stage_table);	
		var places = document.getElementsByClassName("place", stage_table);	
		
		if( wrongs.length == 0 && places.length == 0 ) {
			clearInterval( clockInterval );
			var congrat = "";
			
			if( lang == "en" ){
				congrat = "<div id='congratulations'><h1>Congratulations!</h1>You solved the puzzle using "+joker_count+" joker and "+check_count+" times the check button in ";
			} else if ( lang == "ge" ){
				congrat = "<div id='congratulations'><h1>Gratulation!</h1>Sie haben das Spiel mit "+joker_count+" joker(n) und mit "+check_count+" mal verwendetem kontollieren button in ";
			} else if ( lang == "tr" ){
				congrat = "<div id='congratulations'><h1>Tebrikler!</h1>Oyunu "+joker_count+" key jokere ve "+check_count+" kez kontrole basarak ";
			}
			
			if( cMin >= 60 ){
				if( lang == "en" ){ congrat += "more than a hour (poor performance).</div>"; }
				else if( lang == "ge" ){  congrat += "mehr als einer Stunde gelöst (schwache Leistung).</div>"; }
				else if( lang == "tr" ){  congrat += "bir saatden fazla olan bir süreçte anca bitirebildiniz (pek hızlı sayılmaz).</div>"; }
			} else {
				if( lang == "en" ){ congrat += cMin + " min. and " + cSec + " sec.</div>"; }
				else if( lang == "ge" ){  congrat += cMin + " min. und " + cSec + " sec. gelöst,</div>"; }
				else if( lang == "tr" ){ congrat += cMin + " dak. ve " + cSec + " san. içinde bitirdiniz.</div>"; }
				
			}
			document.getElementById("stage_container").innerHTML = congrat;
		} else {
			check_count++;	
		}
}

function getRandom(min, max, except){
	var factor = max - min + 1;
	var rand = Math.floor( Math.random() * factor ) + min;
	//if( except != null && except.length > 5 ) { return 0; }
	
	if( except != null && except.length > 0 ) {
		except = removeDuplicates( except );
		//debug( except.length +" : " + except.join( ", " ));
		
		if( except.length >= 9 ) {
			return -1;
		}
		
		var found = false;
		for( var i = 0; i < except.length; i++ ) {
			if( except[i] == rand ) {
				found = true;
				break;
			}
		}
		if( found == true ) {
			rand = getRandom(min, max, except);	
		}
	}
	return rand;
}

function removeDuplicates(nums){
	nums.sort();
	var newNums = new Array();
	for( var i = 0; i < nums.length; i++ ){
		var found = false;
		for( var j = 0; j < newNums.length; j++){
			if( newNums[j] == nums[i] ){
				found = true;
				break;
			}
		}
		
		if( found == false ) {
			newNums.push(nums[i]);	
		}
	}
	return newNums;
}


function createNumbers() {
	var table = "<table id=\"numbers\" width=\"360\" height=\"40\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>";
	for( var i = 1; i < 10; i++ ) {
		table += "<td><div class=\"number_selectable\" id=\"" + i + "\" onClick=\"markNumber(this)\">" + i + "</div></td>";
	}
	table += "</tr></table>";
	return table;
}

function markNumber(obj){
	var number_table = document.getElementById("numbers");
	var divs = document.getElementsByClassName("number_selected", number_table);
	for( var i = 0; i < divs.length; i++){
		divs[i].className = "number_selectable";
	}
	current_number = obj.innerHTML;
	obj.className = "number_selected";	
}

function eraser(){
	if( eraser_on == false ) {
		document.getElementById('menu_eraser').innerHTML = "rubber on";
		eraser_on = true;
	} else {
		document.getElementById('menu_eraser').innerHTML = "rubber off";
		eraser_on = false;
	}
}

function debug(text){
	document.getElementById('debug').innerHTML += "<pre>" + text + "</pre>";
}

function add_divs(table, tag, classname)
{
	var items = table.getElementsByTagName(tag);
	for (var i = 0; i < items.length; i++)
		items[i].innerHTML =
			"<div class='" + classname + "'>" + items[i].innerHTML + "</div>";
}

function showCombos( sum, arity, smallest, list ) {
	var combos = document.getElementById('combos');
	combos.innerHTML = "<h1>Possible Combinations ...</h1>";
	splitSums( sum, arity, smallest, list );
}

function splitSums( sum, arity, smallest, list ) {
	if( sum == 0 && arity == 0 ) {
		 document.getElementById('combos').innerHTML += "<p>" + list.substring( 1, list.length ) + "</p>";
		return;
	}
	
	if( sum <= 0 || arity <= 0 ) {
		return;	
	}
	
	for( var i = smallest; i <= 9; i++ ){
		splitSums( sum - i, arity - 1, i+1, list + ", " + i );	
	}
}