// Decide browser version (taken from YouPlay)
var ns4 = (navigator.appName == 'Netscape' && parseInt(navigator.appVersion) == 4);
var ns6 = (document.getElementById)? true:false;
var ie4 = (document.all)? true:false;
//if (ie4) var docRoot = 'document.body';
var ie5 = false;
//if (ns4) {
//  var oW = window.innerWidth;
//  var oH = window.innerHeight;
//  window.onresize = function () {if (oW!=window.innerWidth||oH!=window.innerHeight) location.reload();}
//}


// UR-functions

function make_visible(obj_id){
  if( document.getElementById(obj_id)) document.getElementById(obj_id).style.visibility  ='visible';
}

function make_hidden(obj_id){
  if( document.getElementById(obj_id))    document.getElementById(obj_id).style.visibility  ='hidden';
}

function change_source(img_id,img_src){
  if( document.getElementById(img_id))    document.getElementById(img_id).src =img_src;
}

function change_size(img_id,new_width,new_height){
  if( document.getElementById(img_id)){
    document.getElementById(img_id).width =new_width;
    document.getElementById(img_id).height=new_height;
  }
}


function move_around(thing_id,where_x,where_y){
  if(document.getElementById(thing_id)){
    if (ie4) { document.getElementById(thing_id).style.posTop = where_y;     document.getElementById(thing_id).style.posLeft = where_x;}
    if (ns4) { document.getElementById(thing_id).style.top = where_y + 'px'; document.getElementById(thing_id).style.left = where_x + 'px';}
    if (ns6) { document.getElementById(thing_id).style.top = where_y;        document.getElementById(thing_id).style.left = where_x;}
  }
}

function compute_arrow_parameters(read_start_x,read_start_y,read_end_x,read_end_y)
{
  //external variables: step_height, step_width needed to slightly offset arrows and choose width and height if vertical or horizontal
  // returned properties: arrow_dir , arrow_corn_x , arrow_corn_y , arrow_width , arrow_height
  // external: step_height and step_width; UGLY!!! and different for other divs!!!
  // cleanup:  fixes centre of arrow
  var cleanup_hor=15;
  var cleanup_ver=7;
  // nilarrow: for circle
  var nil_arrow_height=30;
  var nil_arrow_width=35;
  // hor/vertarrow: for hor/vert
  var vert_arrow_height=20;
  var hor_arrow_width=30;

  if( (read_end_y -0)-(read_start_y-0) > 10)
  {
    // south-east (\)
    if((read_end_x -0)-(read_start_x-0) > 10){
      this.arrow_dir='se';
      this.arrow_corn_x= (read_start_x-0)  + (cleanup_hor-0) -3;
      this.arrow_width=  (read_end_x-0)    - (read_start_x -0);
      this.arrow_corn_y= (read_start_y -0) + (cleanup_ver-0) +3;
      this.arrow_height= (read_end_y -0)   - (read_start_y-0);
    }
    // south-west (/)
    else if((read_end_x -0)-(read_start_x-0) < -10){
      this.arrow_dir='sw';
      this.arrow_corn_x= (read_end_x-0)    + (cleanup_hor-0) -3;
      this.arrow_width=  (read_start_x -0) - (read_end_x-0);
      this.arrow_corn_y= (read_start_y -0) + (cleanup_ver-0) -3;
      this.arrow_height= (read_end_y -0)   - (read_start_y-0);
    }
    // south (|)
    else{
      this.arrow_dir='s';
      this.arrow_corn_x=((read_end_x-0)+(read_start_x -0))/2 -2;
      this.arrow_width= hor_arrow_width;
      this.arrow_corn_y= (read_start_y -0) + (cleanup_ver-0);
      this.arrow_height= (read_end_y -0)   - (read_start_y-0);
    }
  }
  else if( (read_end_y -0)-(read_start_y-0) < -10){
    // north-east (/)
    if((read_end_x -0)-(read_start_x-0) > 10){
      this.arrow_dir='ne';
      this.arrow_corn_x= (read_start_x-0)  + (cleanup_hor-0) -3;
      this.arrow_width=  (read_end_x-0)    - (read_start_x -0);
      this.arrow_corn_y= (read_end_y -0)   + (cleanup_ver-0) +3;
      this.arrow_height= (read_start_y-0)  - (read_end_y -0);
    }
    // north-west (\)
    else if((read_end_x -0)-(read_start_x-0) < -10){
      this.arrow_dir='nw';
      this.arrow_corn_x= (read_end_x-0)    + (cleanup_hor-0) +3;
      this.arrow_width=  (read_start_x-0)  - (read_end_x -0);
      this.arrow_corn_y= (read_end_y -0)   + (cleanup_ver-0) -3;
      this.arrow_height= (read_start_y-0)  - (read_end_y -0);
    }
    // north (|)
    else{
      this.arrow_dir='n';
      this.arrow_corn_x=((read_end_x-0)+(read_start_x -0))/2 +2;
      this.arrow_width= hor_arrow_width;
      this.arrow_corn_y= (read_end_y -0) + (cleanup_ver-0);
      this.arrow_height= (read_start_y -0)   - (read_end_y-0);
    }
  }
  else{
    //east(-)
    if((read_end_x -0)-(read_start_x-0) > 0){
      this.arrow_dir='e';
      this.arrow_corn_x=(read_start_x-0)    + (cleanup_hor-0);
      this.arrow_width= (read_end_x-0)-(read_start_x -0);
      this.arrow_corn_y= ((read_end_y-0)+(read_start_y -0))/2 +2;
      this.arrow_height=  vert_arrow_height;
    }
    //west(-)
    else if((read_end_x -0)-(read_start_x-0) < 0){
      this.arrow_dir='w';
      this.arrow_corn_x=(read_end_x-0)    + (cleanup_hor-0);
      this.arrow_width= (read_start_x-0)-(read_end_x -0);
      this.arrow_corn_y= ((read_end_y-0)+(read_start_y -0))/2 -2;
      this.arrow_height=  vert_arrow_height;
    }
    // NIL
    else{
      this.arrow_dir='0';
      this.arrow_height= nil_arrow_height;
      this.arrow_width= nil_arrow_width;
      this.arrow_corn_x=(read_end_x-0);
      this.arrow_corn_y=(read_end_y-0)-5;
    }
  }
}






function change_orders_status (new_status){
  orders_status=new_status;
  if(document.getElementById('status_javabox')) document.getElementById('status_javabox').innerHTML=new_status;
}

function change_attacker(territory_id){
  attacker_territory=territory_id;
  if(document.getElementById('attacker_javabox')) document.getElementById('attacker_javabox').innerHTML=territories_names[territory_id];
  if(document.getElementById('territory_attacked_by_'+territory_id)){
    document.getElementById('attacked_javabox').innerHTML=territories_names[document.getElementById('territory_attacked_by_'+territory_id).value];
    attacked_territory=document.getElementById('territory_attacked_by_'+territory_id).value;
  }
  if(document.getElementById('attacking_units_from_'+territory_id)){
    document.getElementById('attacking_javabox').innerHTML=document.getElementById('attacking_units_from_'+territory_id).value;
    attacking_units=document.getElementById('attacking_units_from_'+territory_id).value;
  }
  if(document.getElementById('units_built_in_'+territory_id)){
    document.getElementById('built_javabox').innerHTML=document.getElementById('units_built_in_'+territory_id).value;
    units_built=document.getElementById('units_built_in_'+territory_id).value;
  }
  change_orders_status ('choose attacked');
  adjust_preview_arrow(attacker_territory,attacked_territory);
}


function change_attacked(territory_id){
  if(document.getElementById('territory_attacked_by_'+attacker_territory)) {
    var neighbours_number=document.getElementById('territory_attacked_by_'+attacker_territory).length;
    var j;
    var borders='no';
    for (j=0;j<neighbours_number;j++)
    {
      if(territory_id==document.getElementById('territory_attacked_by_'+attacker_territory).options[j].value)
      {
        attacked_territory=territory_id;
        if(document.getElementById('attacked_javabox')) document.getElementById('attacked_javabox').innerHTML=territories_names[territory_id];
        borders='yes';
        adjust_preview_arrow(attacker_territory,attacked_territory);
      }
    }
    if(borders=='no')
    {
      if(document.getElementById('territory_attacked_by_'+territory_id))
      {
        reset_all();
        change_attacker(territory_id);
      }
      else
        alert('Sorry. '+territories_names[attacker_territory]+' does not border on '+territories_names[territory_id]+', and you do not own '+territories_names[territory_id]+'. Please select another territory to attack/transfer to. If you are satisfied with the current order, click on \'Deliver order to troops\' to commit this order. If you do not wish to confirm the current order, click on \'Reset\' to issue an order for another territory.');
    }
  }
  // on reset, it looks for the -1 field
  else document.getElementById('attacked_javabox').innerHTML='(x)';


}
function change_attacking_units(increment){
  if(document.getElementById('attacking_units_from_'+attacker_territory)) {
    var maximum_units=(units_present[attacker_territory]-0)+(units_built-0);
    attacking_units= (attacking_units-0)+increment;
    if( (attacking_units-0) > (maximum_units-0)) attacking_units=maximum_units;
    if(attacking_units<0) attacking_units=0;
    if(attacking_units>1000) attacking_units=1000;
    if(document.getElementById('attacking_javabox')) document.getElementById('attacking_javabox').innerHTML=attacking_units;
  }
}


function adjust_arrow(arrow_territory){
  if(document.getElementById('territory_attacked_by_'+arrow_territory)){
    var arrow_victim= document.getElementById('territory_attacked_by_'+arrow_territory).value;
    if(arrow_victim==0) var arrow_victim= arrow_territory;
    var ArrowData = new compute_arrow_parameters(army_x[arrow_territory],army_y[arrow_territory],army_x[arrow_victim],army_y[arrow_victim]);
    change_source('order_img_'+arrow_territory, 'images/armies/arrow_0_' + ArrowData.arrow_dir + '.gif');
    change_size  ('order_img_'+arrow_territory, ArrowData.arrow_width,    ArrowData.arrow_height);
    move_around  ('order_arrow_'+arrow_territory, ArrowData.arrow_corn_x,   ArrowData.arrow_corn_y);
  }
}

/*
function adjust_preview_arrow(arrow_territory,arrow_victim){
}
*/

function adjust_preview_arrow(arrow_territory,arrow_victim){
  var dummy_territory=arrow_territory;
  var dummy_victim=arrow_victim;
  if(dummy_territory<=0) var dummy_territory= 0;
  if(dummy_victim<=0) var dummy_victim= dummy_territory;
  var ArrowData = new compute_arrow_parameters(army_x[dummy_territory],army_y[dummy_territory],army_x[dummy_victim],army_y[dummy_victim]);
  change_source('prev_img', 'images/armies/arrow_1_' + ArrowData.arrow_dir + '.gif');
  change_size  ('prev_img', ArrowData.arrow_width,    ArrowData.arrow_height);
  move_around  ('prev_arrow', ArrowData.arrow_corn_x,   ArrowData.arrow_corn_y);
  if(dummy_territory > 0) make_visible('prev_arrow');
  else make_hidden('prev_arrow');
}


function reset_all(){
  change_attacking_units(-1000);
  change_built(-1000);
  change_attacker(-1);
  change_attacked(0);
  change_orders_status('choose attacker');
  /*adjust_preview_arrow(0,0);*/
}

function adjust_attack_options(territory_id,units_presentZ){
  document.getElementById('attacking_units_from_'+territory_id).options.length = 0;
  for(i=0;i<=(units_presentZ-0)+(document.getElementById('units_built_in_'+territory_id).value-0);i++)
  {
    if(i<= units_presentZ) document.getElementById('attacking_units_from_'+territory_id).options[i]=new Option(i,i);
    else  document.getElementById('attacking_units_from_'+territory_id).options[i]=new Option(i+'(b)',i);
  }
}



function sup_smart_shortcuts (territory_id)
{
  if(territory_id==attacker_territory) 
  {
    change_attacking_units(-1000);
    if(attacked_territory == 0) deliver_order();
    else change_attacked(0);
  }
  else if(orders_status=='choose attacked') 
  {
    if(territory_id==attacked_territory) deliver_order();
    else 
    {
      change_attacked(territory_id); 
      change_attacking_units(+1000);
    }
  }
  else if(document.getElementById('territory_attacked_by_'+territory_id)) change_attacker(territory_id);
  else alert('Unfortunately, you cannot issue orders for a territory you do not own.');
}





/* OBSOLETE, OVERRIDDEN BY CALSIR'S FUNCTIONS
function binomial_computator(units,chance){
  var topmost=2000;
  var outcomes=new Array;
  var j,k,gotcha;
  var probabilities=new Array;
  var mean_value=0;
  var min_range=-1,max_range=-1;
  var chatter='';
  //initialise outcomes----
  for (k=1;k<=units;k++)
  {
    outcomes[k]=0;
  }
  // try result------------
  for (j=1;j<=topmost;j++)
  {
    gotcha=0;
    for (k=1;k<=units;k++)
    {
      if(Math.random()<=chance) gotcha++;
    }
    outcomes[gotcha]++;
  }
  //check range------------
  for (k=1;k<=units;k++)
  {
    probabilities[k]=Math.round(outcomes[k]*100/topmost);
    mean_value+=k*probabilities[k]
    if(probabilities[k]>0)
    {
      if(min_range==-1) min_range=k;
      max_range=k;
    }
  }
  //say results------------
  for (k=min_range;k<=max_range;k++)
  {
        if(k<10) chatter+='0';
        if(k<100) chatter+='0';
        chatter+=(k+' damage: |');
        for(j=1;j<=probabilities[k];j++)
        {
          chatter+='x';
        }
        chatter+=('\t ('+probabilities[k]+'%)');
        chatter+=('\n');
  }
  var mode_names=new Array;
  mode_names[0.4]='in a skirmish';
  mode_names[0.6]='in attack';
  mode_names[0.8]='in defence';
  alert('Probabilities for '+units+' units '+mode_names[chance]+':\n'+chatter+'\nWarning. This is only a numerical estimation. An error of a few %s is likely.\n(computed mean: '+(mean_value/100)+', true mean: '+(units*chance)+')');
}
*/

/*---------------------------- Courtesy of Calsir ----------------------------------------------*/

/* KillProbabilityCalculator adapted from Calsir's version 1.01, based on some conceptual code by BlckKnght */

function killProbabilityCalculator(nArg, pkArg)
{
    // Parameters
    var maxNumberOfBins = 15;
    var maxNumberOfColumns = 15;
    var showCheckSum = false;
    var histChar = 'x';
    var ghostChar = '0';

    // Variables
    var n = parseInt(nArg);
    var pk = parseFloat(pkArg);
    var killsP = new Array;
    var killsTemp = [0, 0];

    var killsMean = n * pk;
    var killsStdDev = 0;
    var killsVar = 0;
    var pSum = 0;
    
    for ( var i = 0; i <= n/2; i++) {
    	killsTemp = binomialProbability(n, i, pk);
		killsP[i] = killsTemp[0];
		killsP[n-i] = killsTemp[1];
	}
    
    for ( i = 0; i<=n; i++) {
    	killsVar += killsP[i] * Math.pow(i - killsMean, 2);
    	pSum += killsP[i];
    }

    killsStdDev = Math.sqrt(killsVar);

    var binParameters = binsMinMaxSizeNumber(n+1, maxNumberOfBins, killsStdDev, killsMean);
    
    var textOutput = new String("");
    textOutput += "Expected units killed: " +(Math.round(killsMean*10)/10)+ " +/- "+(Math.round(killsStdDev*10)/10);
    textOutput += "\n_______________________________________________________";
    textOutput += "\n" + verticalHistogram(maxNumberOfColumns, binParameters, killsP, histChar, ghostChar);

		
    if (showCheckSum == true) {
    	var logPSum = Math.round(Math.log(Math.abs(pSum-1))*Math.LOG10E);
    	if(pSum == 1) {
    		textOutput += "; pSum = 1.";
    	} else {
    		textOutput += "; log10(pSum) = "+logPSum+".";
    	}
	}
/*
	else {
		textOutput += ".";
	}
*/

    alert(textOutput);
}

//	Obsolete, not used.
function binomialCoefficients(n, k)
{   

//  Initial pseudocode by BlckKnght, refined by Calsir.

    var r = Math.max(k,n-k);
    var result = 1.0;

    if ((k<=0) || (k>=n)) {
        return 1;
    }
    
    for(var i = n; i>r; i--){
        result *= i/(i-r);
    }
    
    return result;
}

function binomialProbability(n, k, p) 
{
    var r = Math.max(k,n-k);
    var s = n-r;
    var result = [0, 0];
    var np = 1-p;
    var pnp = p*np;
    var maxRem = r-s;
    var pK = 1, pNK = 1, pIter = 1;
    var condExp = Math.floor((r-s)/s);
    var pCond = Math.pow(p, condExp);
    var npCond = Math.pow(np, condExp);
    var remExp = maxRem; 
    
    if (k<=0) {
    	pK = Math.pow(np,n);
    	pNK = Math.pow(p,n);
    } else if (k>=n) {
    	pK = Math.pow(p,n);
		pNK = Math.pow(np,n);
    } else {
		for (var i=n; i>r; i--) {
			pIter=pnp*i/(i-r);
			
			pK *= pIter*npCond;
			pNK *= pIter*pCond;
			remExp -= condExp;
		}
	
		pK *= Math.pow(np,remExp);
		pNK *= Math.pow(p,remExp);
    }
    
    result = [pK, pNK];
    return result;
}

function binsMinMaxSizeNumber(numberOfResults, maxNumberOfBins, stdDev, mean)
{
    var minPossibleBin = 0;
    var maxPossibleBin = numberOfResults-1;
    var binSize; // = Math.max(1, Math.floor(numberOfResults/maxNumberOfBins));
    var centreBin = mean;
    
    var minBin;// = centreBin - binSize*Math.floor(maxNumberOfBins/2);
    
    minBin = Math.max(Math.round(centreBin - 3*stdDev), minPossibleBin);
    
    
    var maxBin; // = minBin + binSize*maxNumberOfBins;
    
    maxBin = Math.min(Math.round(centreBin + 3*stdDev),maxPossibleBin);
        
    binSize = Math.max(1, Math.floor((maxBin - minBin)/maxNumberOfBins));
    
    var binNumber = Math.max(Math.ceil((maxBin - minBin+1) / binSize,maxNumberOfBins));
    
    //recentering
    
    minBin = Math.max(Math.floor(centreBin - binSize*(binNumber/2+1/2)), minPossibleBin);
    maxBin = Math.min(minBin + binSize*binNumber, maxPossibleBin);
    
    
    var result = [minBin, maxBin, binSize, binNumber];
    
    return result;
}

function calculateGhostSize(n) {
	if (n>0) {
		return Math.floor(Math.log(n)*Math.LOG10E);
	} else {
		return 0;
	}
}

function addBinToString(binId, ghostCeil, ghostChar) {
	var ghostSize = ghostCeil - calculateGhostSize(binId);
	var ghost = "";
	for(var j=0; j<ghostSize;j++) {
		ghost += ghostChar;
	}
	
	return ("" + ghost + binId);
}

function verticalHistogram(maxNumberOfColumns, binParameters, probabilityDensity, histChar, ghostChar)
{
    var result = new String();
    result = "";
    var minBin = binParameters[0]; //maxBin = binParameters[1]; 
    var binSize = binParameters[2], binNumber = binParameters[3];
    
    var cumulatedBinProbability = new Array;
    
    var i,j,k;
    var minInterval, maxInterval;
    
    var ghostSizeCeil = calculateGhostSize(minBin+binSize*binNumber);
    
    for (i=0; i<binNumber; i++) {
        cumulatedBinProbability[i]=0;
        for (j=0; j<binSize; j++) {
        	k = minBin + i*binSize + j;
            cumulatedBinProbability[i]+= probabilityDensity[k];
        }
    }
    
    var histBasicLength = Math.max.apply( Math, cumulatedBinProbability)/maxNumberOfColumns;
        
    for (i = 0; i<binNumber; i++) {
        minInterval = minBin + i*binSize;
        maxInterval = minInterval + binSize-1;
        
        histLineLength = Math.floor(cumulatedBinProbability[i]/histBasicLength);
        
        result += addBinToString(minInterval, ghostSizeCeil, ghostChar);
        if (binSize > 1) {
			result += (" - "+ addBinToString(maxInterval, ghostSizeCeil, ghostChar));
		}
        result +=" damage: |";
        for (j=0; j < histLineLength; j++) {
            result += histChar;
        }
        
        result += ("\t (" +(Math.round(cumulatedBinProbability[i]*1000)/10)+"%) \n");
    }
    
    return result;
}


