Source for "Conquer Club - BOB"

By yeti_c
Has no other scripts.


the source is over 100KB, syntax highlighting in the browser is too slow

// Conquer Club - Card Counter, Card Redemption Value, Status Indicator
var versionString = "4.4.8";

//  
//  This monkey is now called 
//





             /////    ////   /////      
             //  //  //  //  //  //     
             /////   //  //  /////      
             //  //  //  //  //  //     
             /////    ////   /////      






// Credit for the name goes to yeti_c
// Temporary Territory Fix by mfontolan
// 27-Aug-07 - Temp Clock Fix by mfontolan



//
//  
//    PLEASE READ ALL THE COMMENTS AT THE START OF THIS FILE BEFORE EDITING 
//  
//-----------------------------------------------------------------------------
// Installation
//-----------------------------------------------------------------------------
// This is a Greasemonkey user script.
//
// To use, first install Greasemonkey: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "Conquer Club - BOB", and click Uninstall.
//
//-----------------------------------------------------------------------------
//  Meta Data - required for Greasemonkey
//-----------------------------------------------------------------------------
// ==UserScript==
// @name          Conquer Club - BOB
// @namespace     http://yeti_c.co.uk/conquerClub
// @description   Adds Stats, card counter, redemption value, animated clock, text based map, map inspection tools
// @include       http://*conquerclub.com*
// ==/UserScript==

// 
//-----------------------------------------------------------------------------
// DO NOT EDIT BELOW THIS ( unless you know what you are doing )
//-----------------------------------------------------------------------------
// NO REALLY, THERE IS NO NEED TO EDIT THIS FILE ALL OPTIONS ARE CONTROLLED BY THE GAME MENU
//
//
//  I mean it dont even read past here


















// If you are still reading then on your own head be it, however pleaae post your modification to this thread
// http://www.conquerclub.com/forum/viewtopic.php?t=33445 so that I can look at improving the script.

//-----------------------------------------------------------------------------
//  Please Wait coding - creates a Div that gets in the way of people doing things!
//-----------------------------------------------------------------------------


// Start/stop please wait...
function startWaiting() { showPleaseWait(true);  }
function stopWaiting()  { showPleaseWait(false); }

// Start please wait with custom message
function customStartWaiting(msg) 
{
	startWaiting();
	var pleaseWaitCaption = document.getElementById('pleaseWaitMessage');
	if (pleaseWaitCaption)
		pleaseWaitCaption.innerHTML = msg;
}

// Functions for showing/hiding please wait message
function showPleaseWait(show)
{
	var pleaseWait = document.getElementById('pleaseWait');
	if (!pleaseWait)
		pleaseWait = createPleaseWait();
	if (pleaseWait)
	{
		if (show) 
			pleaseWait.style.display = "";
		else 
			pleaseWait.style.display = "none";
	}
}

function createPleaseWait()
{
	var opacity = "0.5";
	var backColour = "#000000";
	var frontColour = "#FFFFFF";
	
	
	var pleaseWait = document.createElement('div');
	pleaseWait.id = "pleaseWait";
	pleaseWait.style.position = "absolute";
	pleaseWait.style.height = "100%";
	pleaseWait.style.width = "100%";
	pleaseWait.style.display = "none";
	pleaseWait.style.zIndex = "99";
	pleaseWait.style.top = "0";
	pleaseWait.style.left = "0";

	// Show please wait over central column only.
	var midcol = document.getElementById("middleColumn");
	if (midcol) // note it may not exist in secondary included pages like topic review
		document.getElementById("middleColumn").appendChild(pleaseWait);
	else
		return;


	var pwTable = document.createElement('table');
	pwTable.style.height = "100%"
	pwTable.style.width = "100%";
	pwTable.cellSpacing = "0";
	pwTable.cellPadding = "0";

	var pwRow1 = document.createElement('tr');
	pwRow1.style.height = "300px";
	pwRow1.style.verticalAlign = "top";

	var pwTdRow1 = document.createElement('td');
	pwTdRow1.style.backgroundColor = backColour;
	pwTdRow1.style.opacity = opacity;
	pwTdRow1.colSpan = '3';


	var pwRow2 = document.createElement('tr');
	pwRow2.style.height = "1px";
	pwRow2.style.padding = "0px";


	var pwTd1Row2 = document.createElement('td');
	pwTd1Row2.style.backgroundColor = backColour;
	pwTd1Row2.style.opacity = opacity;
	pwTd1Row2.style.width = "25%";


	var pwTd2Row2 = document.createElement('td');

	pwTd2Row2.style.padding = "0px 0px 0px 0px";
	pwTd2Row2.style.backgroundColor = frontColour;
	pwTd2Row2.style.border = "1px";
	pwTd2Row2.style.padding = "10px";
	pwTd2Row2.style.borderStyle = "solid";
	pwTd2Row2.style.opacity = 1;

	var pwMessageTable = document.createElement('table');
	pwMessageTable.style.backgroundColor = frontColour;
	pwMessageTable.style.color = "#000000";
	pwMessageTable.style.padding = 0;
	pwMessageTable.style.width = "100%";
	pwMessageTable.style.height = "100%";


	var pwMessTableRow = document.createElement('tr');
	pwMessTableRow.style.padding = 0;


	var pwMessTableImageCell = document.createElement('td');
	pwMessTableImageCell.style.padding = 0;
	pwMessTableImageCell.style.width = "75px";
	
	
	var pwMessTableImage = document.createElement('img');
	pwMessTableImage.id = "pleaseWaitImage";
	pwMessTableImage.src = "http://www.conquerclub.com/static/loading.gif";
	pwMessTableImage.style.paddingRight = "2px";

	var pwMessTableCell = document.createElement('span');
	pwMessTableCell.id = "pleaseWaitMessage";
	pwMessTableCell.style.padding = 0;


	var pwTd3Row2 = document.createElement('td');
	pwTd3Row2.style.backgroundColor = backColour;
	pwTd3Row2.style.opacity = opacity;
	pwTd3Row2.style.width = "25%";


	var pwRow3 = document.createElement('tr');
	pwRow3.style.height = "100%";
	pwRow3.style.verticalAlign=  "top";


	var pwTdRow3 = document.createElement('td');
	pwTdRow3.style.backgroundColor = backColour;
	pwTdRow3.style.opacity = opacity;
	pwTdRow3.colSpan = '3';

	pwRow1.appendChild(pwTdRow1);

	pwTd2Row2.appendChild(pwMessageTable);

	pwMessTableImageCell.appendChild(pwMessTableImage);
	pwMessTableImageCell.appendChild(pwMessTableCell);

	pwMessTableRow.appendChild(pwMessTableImageCell);

	pwMessageTable.appendChild(pwMessTableRow);

	pwRow2.appendChild(pwTd1Row2);
	pwRow2.appendChild(pwTd2Row2);
	pwRow2.appendChild(pwTd3Row2);

	pwRow3.appendChild(pwTdRow3);

	pwTable.appendChild(pwRow1);
	pwTable.appendChild(pwRow2);
	pwTable.appendChild(pwRow3);


	pleaseWait.appendChild(pwTable);

	return pleaseWait;
}


//-----------------------------------------------------------------------------
//  DEFAULT OPTIONS SETTINGS
//-----------------------------------------------------------------------------

// THERE IS NO POINT IN EDITING THESE: CHANGES HERE WILL HAVE NO EFFECT
// There are TWO ways to edit the settings, EASY WAY: Use the new settings menu.
// HARD WAY. Go to about:Config in FireFox and - Search for BOB.OPTIONS.
// Then Edit that value - BE CAREFULL if you get the format wrong the script will crash, 
// if you crash it and want to recover, set that option value to exactly the next 4 chars ({}) 
// this will re load the defaults below.
var DEFAULT_OPTIONS = new Object();
DEFAULT_OPTIONS['jumptomap'] = false;
DEFAULT_OPTIONS['textMapType'] = "Standard";
DEFAULT_OPTIONS['fadeMap'] = 1; // 0 = No Fade  1 = Total WhiteOut
DEFAULT_OPTIONS['MapLeft'] = 0;
DEFAULT_OPTIONS['MapTop'] = 0;
DEFAULT_OPTIONS['24hourClockFormat'] = "am/pm";
DEFAULT_OPTIONS['mapInspect'] = true;
DEFAULT_OPTIONS['confirmEnds'] = true;
DEFAULT_OPTIONS['confirmAutoAttack'] = true;
DEFAULT_OPTIONS['confirmDeploy'] = true;
DEFAULT_OPTIONS['statsMode'] = "Extended";
DEFAULT_OPTIONS['floatActions'] = "Off";
DEFAULT_OPTIONS['hideMenu'] = "Off";
DEFAULT_OPTIONS['MinimumFormWidth'] = "600";
DEFAULT_OPTIONS['ccdd'] = "On";
DEFAULT_OPTIONS['fulllog'] = "Off";
DEFAULT_OPTIONS['swapavas'] = "Off";
var startLogTime = Math.round((new Date()).getTime()/1000)
var Logging =  "";

//-------------------------------------------------------------------------
//    OBJECTS
//-------------------------------------------------------------------------

    //Reinforcements Object
    function Reinforcement(lower, upper, divisor)
    {
    	this._lower = lower;
    	this._upper = upper;
    	this._divisor = divisor;
    }

    //Player Class
    function Player( name, pid, color ){
        this._name = name;
        this._pid = pid;
        this._color = color;
        this._cards = 0;
        this._armies = 0;
        this._countries = 0;
	this._calculatedCountries = 0;
        this._continentBonus = 0;
        this._territoryBonus = 0;
	this._lastBonus = 0;
	this._lastBonusFixed = false;
	this._deferred = 0;
        this._skipped = 0;
        this._continents = new Array();
        this.toString = function() { return  this._name; }
	this.getArmiesPerTurn = function()
	{
	}
        this.getTurninP = function() { if( this._cards < 3 ) return 0; if( this._cards > 4 ) return 1; if( this._cards == 3 ) return 0.3341; return 0.778; }
        this.alert = function() {
            alert(    "Name:\t"            +    this._name        +
                    "\nPID:\t"            +    this._pid        +
                    "\nCards:\t"        +    this._cards        +
                    "\nArmies:\t"        +    this._armies    +
                    "\nCountries:\t"    +    this._countries +
                    "\nArmies/Turn:\t"  +    this.getArmiesPerTurn()
            );
        }
        this.killToReduce = function() { 
            if( this._countries < 12 ) return "-"; 
            var rem = (this._countries/3 - Math.floor(this._countries/3));    
            return (rem==0)?"*": ( rem < 0.5 ? "**" : "***") ; 
            }
        this.calcKillToReduce = function() { 
            if( this._calculatedCountries < 12 ) return "-"; 
            var rem = (this._calculatedCountries/3 - Math.floor(this._calculatedCountries/3));    
            return (rem==0)?"*": ( rem < 0.5 ? "**" : "***") ; 
            }
    this.ContinentsDisplay = function ContinentsDisplay() 
    {
        var ret = "";
        var contSum = new Array();
        var flashList = new Array();
        for (var cntn  in this._continents) 
        {
            var ctn = continentsArray[this._continents[cntn]];
            if (typeof(contSum[ctn._name])=="undefined")
                {
                    contSum[ctn._name] =  ctn._bonus;
                    flashList[ctn._name] =  ctn._realName;
                }
                else 
                {
                    contSum[ctn._name] += ctn._bonus;
                    flashList[ctn._name] +=  "|" + ctn._realName;
                }
            
        }
        for (var cntnn  in contSum ) 
        {

            ret += '<span class="JumpClick" title="' + flashList[cntnn] + '">' + cntnn.replace(" ","&nbsp;") + "&nbsp(" + contSum[cntnn] + ") </span>";
        }
        var contSum = new Array();
        var flashList = new Array();
        for (country in countriesArray) 
        {
		var cnt = countriesArray[country];

		if ((cnt._bonus!=0) && (cnt._pid == this._pid))
		{
			if (typeof(contSum[cnt._name])=="undefined")
                	{
                    		contSum[cnt._name] =  cnt._bonus;
                    		flashList[cnt._name] =  cnt._name;
                	}
			else 
			{
				contSum[cnt._name] += cnt._bonus;
				flashList[cnt._name] +=  "," + cnt._name;
			}
		}
        }
        for (var cntnn  in contSum ) 
        {
            ret += '<span class="clickJump" title="' + flashList[cntnn] + '">' + cntnn.replace(" ","&nbsp;") + "&nbsp[" + contSum[cntnn] + "] </span>";
        }
        return ret;

    }
    }
    
    // Country Class
    function Country (name,pid,armies) {
        this._name = name;
        this._pid = pid;
        this._armies = armies;
        this.toString = function() { return this._name; }
        this._borders = new Array();
        this._DefendBorders = new Array();
        this._AttackBorders = new Array();
        this._bombards = new Array();
        this._bombardedBy = new Array();
        this._inContenent = false;
	this._bonus = 0;
	this._killer = false;
	this._neutral = 0;
        this._smallxPos = 0;
        this._smallyPos = 0;
        this._largexPos = 0;
        this._largeyPos = 0;
        this.isSafe = function () {
            var howSafe = 2;
           
            for (var k =0; k < this._borders.length && howSafe > 0; k++){
                var bb = countriesArray[this._borders[k]];
                if (bb._pid != this._pid) {
                    // it's not mine
                    howSafe = 1
                    if (teamNumber(bb._pid) != teamNumber(this._pid)) {
                        // And it's not team
                        howSafe = 0
                        
                    }
                }
            }
            for (var k =0; k < this._DefendBorders.length && howSafe > 0; k++){
                var bb = countriesArray[this._DefendBorders[k]];
                if (bb._pid != this._pid) {
                    // it's not mine
                    howSafe = 1
                    if (teamNumber(bb._pid) != teamNumber(this._pid)) {
                        // And it's not team
                        howSafe = 0
                        
                    }
                }
            }
            return howSafe;
        }
        this.textMap = function () { 
            var txtMapHtml2 = "";
            var txtMapHtmlA = "";
            var txtMapHtmlD = "";
            var txtMapHtmlC = "";
            var txtMapHtmlE = "";
            var txtMapHtmlF = "";
            var aAttack = new Array();
            var aDefend = new Array();
            
            for (var k =0; k < this._borders.length; k++){
                var bb = countriesArray[this._borders[k]];
                aAttack[bb._name] = bb;
            }
            for (var k =0; k < this._DefendBorders.length; k++){
                var bb = countriesArray[this._DefendBorders[k]];
                aDefend[bb._name] = bb;
            }
                
            
            txtMapHtml2 += this.displayString(); 
                    for (var k =0; k < this._borders.length; k++){
                        var bb = countriesArray[this._borders[k]];
                         if (typeof(aDefend[bb._name])=="undefined"){
                                txtMapHtmlA +=  bb.displayString();
                            }
                            else
                            {
                                txtMapHtmlC +=  bb.displayString();
                            }
                    }
                    //txtMapHtml2 += ' ] <= [';
                    
                    for (var k =0; k < this._DefendBorders.length; k++)
		    {
                        var bb = countriesArray[this._DefendBorders[k]];
                        
                        if (typeof(aAttack[bb._name])=="undefined")
			{
                                txtMapHtmlD += bb.displayString();
                        }
                    }

                    for (var k =0; k < this._bombards.length; k++)
		    {
                        var bb = countriesArray[this._bombards[k]];
                        txtMapHtmlE += bb.displayString();
                    }

                    for (var k =0; k < this._bombardedBy.length; k++)
		    {
                        var bb = countriesArray[this._bombardedBy[k]];
                        txtMapHtmlF += bb.displayString();
                    }


                    if (txtMapHtmlC != "") 
		    {
                        txtMapHtml2 += ' <=> [ ' + txtMapHtmlC + ' ]';
                    }
                    if (txtMapHtmlA != "") 
		    {
                        txtMapHtml2 += '<br> Attack only [ ' + txtMapHtmlA + ' ]';
                    }
                    if (txtMapHtmlD != "") 
		    {
                        txtMapHtml2 += '<br> Defend only [ ' + txtMapHtmlD + ' ]';
                    }
                    if (txtMapHtmlE != "") 
		    {
                        txtMapHtml2 += '<br> Bombards [ ' + txtMapHtmlE + ' ]';
                    }
                    if (txtMapHtmlF != "") 
		    {
                        txtMapHtml2 += '<br> Bombarded by [ ' + txtMapHtmlF + ' ]';
                    }
                    
                    
                return  txtMapHtml2;
         }
         this.displayString = function () 
	 {
		var pid = this._pid;
	 	if (pid == UID)
			pid = NID;
		result = '<span class="playerBG' + pid + '"><span class="clickJump" title="' + this._name + '" >'  + this._name + ' (' +  this._armies + ')';
		if (this._bonus != 0)
			result += ' ['+this._bonus+']';
		result += '</span> </span>';
		return result;
         }
    }

    //Continent Class - Note all Continents now have required elements
    // If a Traditional continent - then required matches the size of the countrys array.
    function Continent (name,bonus,realname) {
        this._name = name;
        this._realName = realname;
        this._bonus = bonus;
	this._required = 0;
        this.toString = function() { return this._name; }
        this._countrys = new Array();
        this._continents = new Array();
        this._owners = new Array(); // hold the owners of this continent (note could be many more than one)
	this._overrides = new Array(); // Hold overriders for this continent.
	this._overriden = new Array(); // hold an array to match the owners to say if this is overriden or not.
	this.clearOwners = function() // clean out owners array - called before processing.
		{
			this._owners = new Array();
			this._overriden = new Array();
		}
        this.alert = function() {
            alert(    "Name:\t"            +    this._name        +
                    "\nrealName:\t"            +    this._realName        +
                    "\nBonus:\t"        +    this._bonus        +
                    "\nRequired:\t"        +    this._required        +
                    "\nCountries:\t"    +    this._countrys +
                    "\nOverrides:\t"    +    this._overrides +
                    "\nOwners:\t"  +    this._owners +
                    "\nOverriden:\t"    +    this._overriden);
        }
    }

	function objective (name, realname)
	{
		this._name = name;
		this._realname = realname;
		this._countrys = new Array();
	        this._continents = new Array();
		this._required = 0;
	        this._owners = new Array(); // hold the owners of this objective (note could be many more than one)
		this.clearOwners = function() // clean out owners array - called before processing.
			{
				this._owners = new Array();
			}
	}


//-------------------------------------------------------------------------
//    FUNCTIONS
//-------------------------------------------------------------------------

function deserialize(name, def) 
{
  return eval(GM_getValue(name, (def || '({})')));
}

function serialize(name, val) 
{
  GM_setValue(name, uneval(val));
}

function upgrade(o,name) 
{
    // Copies a default option if there is a missing option.
    if (typeof(o[name]) == "undefined") {
        o[name] = DEFAULT_OPTIONS[name];
    }
     
}
// Load Options 
var myOptions = (deserialize("OPTIONS", DEFAULT_OPTIONS))
if (typeof(myOptions) == "undefined") 
{
    // poor editing in the about:config page
    myOptions = new Object();
}

// LIST ALL OPTIONS HERE 
// This part will handle options MISSING from the config section
upgrade(myOptions,'jumptomap');

upgrade(myOptions,'fadeMap');
upgrade(myOptions,'MapLeft');
upgrade(myOptions,'MapTop');
upgrade(myOptions,'mapInspect');
upgrade(myOptions,'confirmEnds');
upgrade(myOptions,'statsMode');
upgrade(myOptions,'floatActions');
upgrade(myOptions,'hideMenu');
upgrade(myOptions,'MinimumFormWidth');
upgrade(myOptions,'ccdd');
upgrade(myOptions,'fulllog');
upgrade(myOptions,'swapavas');

// REPLACED OPTIONS.
if (typeof(myOptions["showEstimatedArmies"]) != "undefined") {
    delete myOptions["showEstimatedArmies"];
}
if (typeof(myOptions["focuscolor"]) != "undefined") {
    delete myOptions["focuscolor"];
}
if (typeof(myOptions["hoverHighlight"]) != "undefined") {
    myOptions["mapInspect"] = myOptions["hoverHighlight"];
    delete myOptions["hoverHighlight"];
}

// TEXT MAP TYPE
    if (typeof(myOptions["textMapType"]) == "undefined") {
        // textMapType = new option
        if (typeof(myOptions["textMap"]) != "undefined") {
            // we have an option to upgrade.
            if (myOptions["textMap"]) {
                myOptions["textMapType"] = "Extended";
                alert ("This version of the script changes the text map option - there are now two varaitons large and small, you have been upgraded to the large setting which is the same as the previous version");
            }
            else 
            {
                myOptions["textMapType"] = "Off";
            }
            delete myOptions["textMap"];
        }
        else
        {
            upgrade(myOptions,'textMapType');
        }
    }
// CLOCK FORMAT
 if (typeof(myOptions["24hourClockFormat"]) == "undefined") {
  // 24hourClockFormat = new option
        if (typeof(myOptions["24hourClock"]) != "undefined") {
            // we have an option to upgrade.
            if (myOptions["24hourClock"]) {
                myOptions["24hourClockFormat"] = "24h";
             }
            else 
            {
                myOptions["24hourClockFormat"] = "am/pm";
            }
            delete myOptions["24hourClock"];
        }
        else
        {
            upgrade(myOptions,'24hourClockFormat');
           
        }
}
else {
    if (myOptions["24hourClockFormat"] == "AM/PM") {
        myOptions["24hourClockFormat"] = "am/pm";
    }
}
// Confirm Actions
if (typeof(myOptions["confirmAutoAttack"]) == "undefined") {
  if (typeof(myOptions["confirmActions"]) == "undefined") {
    upgrade(myOptions,'confirmAutoAttack');
  }
  else
  {
    myOptions["confirmAutoAttack"] = myOptions["confirmActions"];
  }
}
if (typeof(myOptions["confirmDeploy"]) == "undefined") {
  if (typeof(myOptions["confirmActions"]) == "undefined") {
    upgrade(myOptions,'confirmDeploy');
  }
  else
  {
    myOptions["confirmDeploy"] = myOptions["confirmActions"];
  }
}
 if (typeof(myOptions["confirmActions"]) != "undefined") {
     delete myOptions["confirmActions"];
}
serialize("OPTIONS", myOptions);

function parseTerritory(entry)
{
	var title = entry.getElementsByTagName('name')[0].textContent.normiliseSpaces();
	var pid = parseInt( armiesArr[(i*2)] );
	var amrs = armiesArr[(i*2)+1];
	countriesArray[title] =  new Country (title,pid,amrs);
	var borders = entry.getElementsByTagName('border');

	for (var j = 0; j <borders.length; j++) 
	{
		var bb = borders[j].textContent.normiliseSpaces();

		countriesArray[title]._borders.push(bb);
	}

	countriesArray[title]._smallxPos = entry.getElementsByTagName('smallx')[0].textContent;
	countriesArray[title]._smallyPos = entry.getElementsByTagName('smally')[0].textContent;
	countriesArray[title]._largexPos = entry.getElementsByTagName('largex')[0].textContent;
	countriesArray[title]._largeyPos = entry.getElementsByTagName('largey')[0].textContent;

	bombardments = entry.getElementsByTagName('bombardment');

	for (var j = 0; j <bombardments.length; j++) 
	{
		var bb = bombardments[j].textContent.normiliseSpaces();
		countriesArray[title]._bombards.push(bb);
	}

	var bonusElements = entry.getElementsByTagName('bonus');
	if (bonusElements.length>0)
	{
		var bonus = bonusElements[0].textContent;
		countriesArray[title]._bonus = parseInt(bonus);
	}
	var neutral = entry.getElementsByTagName('neutral');
	if (!neutral.length>0)
	{
		totalStartCountries++;
	}
	else
	{
		killer = neutral[0].getAttribute("killer");
		if (killer=="yes")
		{
			countriesArray[title]._killer=true;
			countriesArray[title]._neutral=neutral[0].textContent;
		}
	}
}

function parseContinent(entry)
{
	var title = entry.getElementsByTagName('name')[0].textContent.normiliseSpaces();
	var dedupename = 1;
	var titleRoot = title
	while (continentsArray[title]) { title = titleRoot + "_" + dedupename++ ; }
	var bonus = parseInt(entry.getElementsByTagName('bonus')[0].textContent);
	var partial = false;
	var required = 0;
	var requiredEl = entry.getElementsByTagName('required');
	if (requiredEl.length>0) // Partial continent - hold required value from XML
	{
		required = parseInt(requiredEl[0].textContent);
		partial = true;
	}

	continentsArray[title] = new Continent(titleRoot,bonus,title);
	var countries = entry.getElementsByTagName('territory');
	for (var j = 0; j <countries.length; j++) 
	{
		var bb = countries[j].textContent.normiliseSpaces();
		continentsArray[title]._countrys.push(bb);
		if (!partial) // Traditional continent we will need to capture how many components there are.
			required++;
	}
	var continents = entry.getElementsByTagName('continent');
	for (var j = 0; j <continents.length; j++) 
	{
		var bb = continents[j].textContent.normiliseSpaces();
		continentsArray[title]._continents.push(bb); 
		if (!partial) // Traditional continent we will need to capture how many components there are.
			required++;
	}
	continentsArray[title]._required = required;
	var overrides = entry.getElementsByTagName('override');
	for (var j = 0; j <overrides.length; j++) 
	{
		var bb = overrides[j].textContent.normiliseSpaces();
		continentsArray[title]._overrides.push(bb); 
	}
}

function parseObjective(entry)
{
	title = entry.getElementsByTagName('name')[0].textContent.normiliseSpaces();
	var dedupename = 1;
	var titleRoot = title
	while (objectivesArray[title]) { title = titleRoot + "_" + dedupename++ ; }
	objectivesArray[title] =  new objective(titleRoot,title);
	var countries = entry.getElementsByTagName('territory');
	for (var j = 0; j <countries.length; j++) 
	{
		var bb = countries[j].textContent.normiliseSpaces();
		objectivesArray[title]._countrys.push(bb); 
		objectivesArray[title]._required++; 
	}
	var continents = entry.getElementsByTagName('continent');
	for (var j = 0; j <continents.length; j++) 
	{
		var bb = continents[j].textContent.normiliseSpaces();
		objectivesArray[title]._continents.push(bb); 
		objectivesArray[title]._required++; 
	}
}

function showKillers()
{
	var ret="";

        var contSum = new Array();
        var flashList = new Array();
        for (country in countriesArray) 
        {
		var cnt = countriesArray[country];

		if (cnt._killer)
		{
			if (typeof(contSum[cnt._name])=="undefined")
                	{
                    		contSum[cnt._name] =  cnt._neutral;
                    		flashList[cnt._name] =  cnt._name;
                	}
			else 
			{
				contSum[cnt._name] += cnt._neutral;
				flashList[cnt._name] +=  "," + cnt._name;
			}
		}
        }
        for (var cntnn  in contSum ) 
        {
            ret += '<span class="clickJump" title="' + flashList[cntnn] + '">' + cntnn.replace(" ","&nbsp;") + "&nbsp[" + contSum[cntnn] + "] </span>";
        }
        return ret;
}

function reinitClock()
{
	var response = unsafeWindow.request.responseText
	if (response)
	{
		response = response.split("&");
		timeStr = response[2];
		if (timeStr.indexOf("span")>-1) // if countdown alert here then strip it out before continuing
		{
			timeStr = timeStr.substring(30,(timeStr.length-7));
		}
		time = timeStr.split("\n");

	/*        hours1 = parseInt(time[0]);
		minutes1 = parseInt(time[1]);
		seconds1 = parseInt(time[2]);*/
		//Yowsers clock fix
		hours1 = parseInt(time[0],10);
		minutes1 = parseInt(time[1],10);
		seconds1 = parseInt(time[2],10); 
	}
}

function getCardType()
{
    var dash = dashboard.innerHTML
    if( dash.indexOf("Escalating") > -1 )
        m_bonusCards = eBonusCards.ESCALATING;
    else if( dash.indexOf("Flat Rate") > -1 )
        m_bonusCards = eBonusCards.FLATRATE;
    else 
        m_bonusCards = eBonusCards.NOCARDS;
}

function recalcRedemption()
{
	RedemptionValue = calcRedemption();
	if(m_bonusCards == eBonusCards.ESCALATING)
		redemption.innerHTML = "<table><tr><td colspan=2>Next Redemption Value is <b>" + RedemptionValue +".</b></td></tr></table>";
	else if(m_bonusCards == eBonusCards.FLATRATE)
		redemption.innerHTML = "<table><tr><td colspan=2><font color=red><b>Red:</b></font> 4&nbsp;<font color=green><b>Green:</b></font> 6&nbsp;<font color=blue><b>Blue:</b></font> 8&nbsp;<b>Mixed:</b> 10</td></tr></table>";
	else 
		redemption.innerHTML = "";
}


function updatePlayerCards()
{
    //    --- Get Player Card Counts ---
    var tmp2 = getElementsByClassName(rightside,"li","status");    
    for ( i in tmp2 ) 
    {
        var indx = tmp2[i].innerHTML.has("Assassin Target") ? 2:1;
        var tmp3 = tmp2[i].textContent.split(/\W/);
        playersArray[pIndxs[i].innerHTML]._cards=parseInt(tmp3[indx]);
    }
}

function getLeft(length)
{
	if (length==1)
		return 6;
	return 2;
}

function GET_MAPLEFT(OPTIONS,mapName) 
{
	var left = 0;
	if (typeof(OPTIONS["MapLeft:"+mapName])=="undefined") 
        {
            left = OPTIONS["MapLeft"];
        }
        else
        {
            left = OPTIONS["MapLeft:" + mapName];
        }
	if (!left)
		left = 0;
	return left;
}


function GET_MAPTOP(OPTIONS,mapName) 
{
	var top = 0;
	if (typeof(OPTIONS["MapTop:"+mapName])=="undefined") 
        {
            top = OPTIONS["MapTop"];
        }
        else
        {
            top = OPTIONS["MapTop:" + mapName];
        }
	if (!top)
		top = 0;
	return top;
}

function GET_MINFORMWIDTH(OPTIONS,mapName) 
{
	var width = 600;
	if (typeof(OPTIONS["MinimumFormWidth:"+mapName])=="undefined") 
        {
            width = OPTIONS["MinimumFormWidth"];
        }
        else
        {
            width = OPTIONS["MinimumFormWidth:" + mapName];
        }
	if (!width)
		width = 600;
	return width;
}


function SHIFT_MAGICMAP(options, name)
{
        var mm = document.getElementById("magicmap");
        left = 12 + GET_MAPLEFT(options,name);
        top = 22 + GET_MAPTOP(options,name);
	mm.style.top= top+"px";
	mm.style.left= left+"px";
}

function checkFloatDice()
{
    if (myOptions["floatActions"] == "On")
    {
	var outerRolls = document.getElementById('rolls');
	if (outerRolls)
	{
		outerRolls.style.position='fixed';
		outerRolls.style.backgroundColor="#EEEEEE";
		outerRolls.style.top=0;
		outerRolls.style.zIndex=2;
	}
	var actionForm = document.getElementById('action-form');
	if (actionForm)
	{
		var mapInspect = document.getElementById('mapinspect');
		var wrapperDiv = document.getElementById('actionWrapper');
		if (document.getElementById('from_country'))
			wrapperDiv.style.paddingTop="22px";
		else
			wrapperDiv.style.paddingTop="0px";
	}
    }
	
}

function showMapInspectDiv()
{
    var mapInspectDiv = document.getElementById('mapinspect');
    var mapInspetHTML = myOptions['mapInspect'] ? "<table><tr><td colspan=2>Map Inspect: <b><span id=hoverInfo /></b></td></tr></table>":"";
    mapInspectDiv.innerHTML = mapInspetHTML;
}


var newfilterTo = unsafeWindow.filterTo;

unsafeWindow.filterTo = 
function(selected) 
{
	newfilterTo(selected);
	colourCodeDD();
};

// Colour codes & Adds army counts to the Dropdown. (Note if Colour Codes is off - then sets class name back to default)
function colourCodeDD()
{
	cc_log("Color Coding the Drop downs");

//     		--- Color Code the TO drop down ---
	var tocountry = document.getElementById('to_country');
	if (tocountry) 
	{
		// We have the to drop down on Screen
		var tcopts = tocountry.options;
		for (var ttt =0 ; ttt < tcopts.length; ttt++)
		{
			var toop = tcopts[ttt];
			var cntry = countriesArray[toop.text];
			if (!cntry) // if we can't find the country - then we need to remove the brackets.
			{
				bracket = toop.text.lastIndexOf("(");
				if (bracket!=-1)
				{
					toop.text = toop.text.substring(0,bracket); // remove stuff after the bracket so that we can find the country OK.
				}
				cntry = countriesArray[toop.text];
			}
			var owner = cntry._pid;
			toop.innerHTML += " (" + cntry._armies + ")";
			if (myOptions['ccdd']=="On")
			{
				toop.className = "playerBGDD"+owner;
			}
			else
			{
				toop.className = "";
			}
		}
	}
//     		--- Color Code the from drop down ---
	var fromcountry = document.getElementById('from_country');
	if (fromcountry) 
	{
		// We have the to drop down on Screen
		var tcopts = fromcountry.options;
		for (var ttt =0 ; ttt < tcopts.length; ttt++)
		{
			var toop = tcopts[ttt];
			var cntry = countriesArray[toop.text];
			if (!cntry) // if we can't find the country - then we need to remove the brackets.
			{
				bracket = toop.text.lastIndexOf("(");
				if (bracket!=-1)
				{
					toop.text = toop.text.substring(0,bracket); // remove stuff after the bracket so that we can find the country OK.
				}
				cntry = countriesArray[toop.text];
			}
			var owner = cntry._pid;
			toop.innerHTML += " (" + cntry._armies + ")";
			if (myOptions['ccdd']=="On")
			{
				toop.className = "playerBGDD"+owner;
			}
			else
			{
				toop.className = "";
			}
		}
	}
}

function prepareMenuHider()
{
    // hide the menu to start with...
    hideMenu();

    // add events to hide the menu again. - occasionally these don't quite work so check they exist before adding events
    var centre = document.getElementById("middleColumn");
    if (centre)
    	centre.addEventListener('mouseover', hideMenu, true);
    var header = document.getElementById("masthead");
    if (header)
    	header.addEventListener('mouseover', hideMenu, true);
    var footer = document.getElementById("footer");
    if (footer)
    	footer.addEventListener('mouseover', hideMenu, true);

    // add div to show the menu.
    showDiv = document.createElement('div');
    showDiv.id="showDiv";
    showDiv.style.position = "absolute";
    showDiv.style.width = "2%";
    showDiv.style.height = document.height+"px";
    showDiv.style.left=0;
    showDiv.style.top=0;
    document.body .appendChild(showDiv);
    showDiv.addEventListener('mouseover', showMenu, true); 
}

function updateMenuHiderHeight()
{
    var showDiv = document.getElementById("showDiv");
    showDiv.style.height = document.height+"px";
}

function hideMenu()
{
	if (myOptions["hideMenu"]=="On")
	{
		hideSideBar();
	}
	else if (myOptions["hideMenu"]=="Game")
	{
		if (document.getElementById("inner-map"))
		{
			hideSideBar();
		}
	}
	else if (myOptions["hideMenu"]=="Site")
	{
		if (!document.getElementById("inner-map"))
		{
			hideSideBar();
		}
	}
	hideMapSettingsMenu();
	hideViewSettingsMenu();
	hideSnapshotsMenu();
	hideConfSettingsMenu();
	hideSiteSettingsMenu();
}

function hideSideBar()
{
	var outerMenu = document.getElementById("outerColumnContainer");
	var leftMenu = document.getElementById("leftColumn");
	if (leftMenu.innerHTML.indexOf('<span class="inbox">')==-1)
	{
		// Don't hide the menu if you have a PM!
		leftMenu.style.display = "none";
		outerMenu.style.borderLeft = "0em solid #DDEEDD";
	}
}

function showMenu()
{
	if (myOptions["hideMenu"]=="On")
	{
		showSideBar();
	}
	else if (myOptions["hideMenu"]=="Game")
	{
		if (document.getElementById("inner-map"))
		{
			showSideBar();
		}
	}
	else if (myOptions["hideMenu"]=="Site")
	{
		if (!document.getElementById("inner-map"))
		{
			showSideBar();
		}
	}
}

function showSideBar()
{
	var outerMenu = document.getElementById("outerColumnContainer");
	var leftMenu = document.getElementById("leftColumn");
	leftMenu.style.display = "inline";
	outerMenu.style.borderLeft = "14em solid #DDEEDD";
}


function setFormWidth()
{
	var width = GET_MINFORMWIDTH(myOptions,mapName);
	if (mapSize=="L")
	{
		lwidth = parseInt(largewidth,10)+5;
		if (lwidth>width)
			width = lwidth;
	}
	else
	{
		swidth = parseInt(smallwidth,10)+5;
		if (swidth>width)
			width = swidth;
	}
	var actionForm = document.getElementById('action-form');
	if (actionForm)
		actionForm.style.width=width+"px";
}

function toggleColourCodeDD()
{
	if (myOptions["ccdd"] == "Off")
	{
		myOptions["ccdd"] = "On";
	}
	else
	{
		myOptions["ccdd"] = "Off";
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_colourcode_dd');
	option.innerHTML = "Colour DropDown: <b>" + myOptions["ccdd"] + '</b>';
	colourCodeDD();
}

function toggleFullLog()
{
	if (myOptions["fulllog"] == "Off")
	{
		myOptions["fulllog"] = "On";
	}
	else
	{
		myOptions["fulllog"] = "Off";
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_fulllog');
	option.innerHTML = "Full Log: <b>" + myOptions["fulllog"] + '</b>';
}

function toggleSwapAvas()
{
	if (myOptions["swapavas"] == "Off")
	{
		myOptions["swapavas"] = "On";
	}
	else
	{
		myOptions["swapavas"] = "Off";
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_swapavas');
	option.innerHTML = "Swap Avatars: <b>" + myOptions["swapavas"] + '</b>';
	swapAvatars();
}

function toggleFloatingActionForm()
{
	// Code below stolen from edthemaster
	var actionForm = document.getElementById('action-form')
	if (myOptions["floatActions"] == "Off")
	{
		myOptions["floatActions"] = "On";
		showMenuOption("menu_hudWidth");
		if (actionForm)
		{
			var mapInspect = document.getElementById('mapinspect');
			actionForm.style.position='fixed';
			actionForm.style.bottom=0;
			actionForm.style.zIndex=2;
			var wrapperDiv = document.createElement('div');
			wrapperDiv.id="actionWrapper";
			if (document.getElementById('from_country'))
				wrapperDiv.style.paddingTop="22px";
			else
				wrapperDiv.style.paddingTop="0px";
			var mapInspect = document.getElementById('mapinspect');
			wrapperDiv.appendChild(mapInspect);
			var cards = document.getElementById('cards');
			if (cards)
			{
				cards = cards.parentNode.parentNode;
				cards.style.backgroundColor="#EEEEEE";
				wrapperDiv.appendChild(cards);
			}
			actionForm.childNodes[1].appendChild(wrapperDiv);
			setFormWidth();
		}
		var outerRolls = document.getElementById('rolls');
		if (outerRolls)
		{
			outerRolls.style.position='fixed';
			outerRolls.style.backgroundColor="#EEEEEE";
			outerRolls.style.top=0;
			outerRolls.style.zIndex=2;
		}
	}
	else
	{
		myOptions["floatActions"] = "Off";
		hideMenuOption("menu_hudWidth");
		if (actionForm)
		{
			var cards = document.getElementById('cards');
			if (cards)
			{
				cards = cards.parentNode.parentNode;
				dashboard.childNodes[1].insertBefore(cards, document.getElementById('outer-rolls').parentNode);
			}

			var mapInspect = document.getElementById('mapinspect');
			dashboard.parentNode.insertBefore(mapInspect, siblings);

			actionForm.style.position='relative'
			actionForm.style.bottom=0
			actionForm.style.zIndex=2 
			actionForm.style.width="100%";
		}
		var outerRolls = document.getElementById('rolls');
		if (outerRolls)
		{
			outerRolls.style.position='relative';
			outerRolls.style.backgroundColor="#EEEEEE";
			outerRolls.style.top=0;
			outerRolls.style.zIndex=2;
		}
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_hud');
	option.innerHTML = "HUD: <b>" + myOptions["floatActions"] + '</b>';
	updateMenuHiderHeight();
}

function toggleTextMap() 
{
	startWaiting();
	if (myOptions["textMapType"] == "Off") 
	{
		myOptions["textMapType"] = "Standard";
	} 
	else if (myOptions["textMapType"] == "Standard") 
	{
		myOptions["textMapType"] = "Extended";
	} 
	else 
	{
		myOptions["textMapType"] = "Off";
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_textMap');
	option.innerHTML = "Text Map: <b>" + (myOptions["textMapType"]) + '</b>';
	setTimeout(doTextMap,100);
}

function doTextMap()
{
	updateTextmap(true);
	APPLY_TEXTMAP(myOptions);
	updateMagicMap(true);
	updateMenuHiderHeight();			
	stopWaiting();
}


function toggleJumpToMap() 
{
	myOptions["jumptomap"] = ! myOptions["jumptomap"];
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_jtm');
	option.innerHTML = "Jump to Map: <b>" + (myOptions["jumptomap"] ? " On" : " Off")+ '</b>';
	if (!myOptions["jumptomap"] )
		window.location.hash="top";
	else 
		window.location.hash="map";
}

function toggleStatsMode() 
{
	if (myOptions["statsMode"] == "Off") 
	{
		myOptions["statsMode"] = "Standard";
	} 
	else if (myOptions["statsMode"] == "Standard") 
	{
		myOptions["statsMode"] = "Extended";
	} 
	else 
	{
		myOptions["statsMode"] = "Off";
	}

	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_stats');
	option.innerHTML = "Stats: <b> " + myOptions["statsMode"] + '</b>';
	APPLY_STATS(myOptions);
	updateMagicMap(false);
	updateMenuHiderHeight();
	stopWaiting();
}

function toggleMagicMap() 
{
	myOptions["mapInspect"] = ! myOptions["mapInspect"];
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_mapInspect');
	option.innerHTML = "Map Inspect: <b>" + (myOptions["mapInspect"] ? " On" : " Off")+ '</b>';
	showMapInspectDiv();
	updateMagicMap(false);
	updateMenuHiderHeight();
	stopWaiting();
}

function toggleConfirmActionsAA() 
{
	myOptions["confirmAutoAttack"] = ! myOptions["confirmAutoAttack"];
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_conf_attack');
	option.innerHTML = "Confirm AutoAttack: <b>" + (myOptions["confirmAutoAttack"] ? " On" : " Off")+ '</b>';
} 
function toggleConfirmActionsDeploy() 
{
	myOptions["confirmDeploy"] = ! myOptions["confirmDeploy"];
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_conf_deploy');
	option.innerHTML = "Confirm Deploy: <b>" + (myOptions["confirmDeploy"] ? " On" : " Off")+ '</b>';
}    
function toggleConfirmEnds() 
{
	myOptions["confirmEnds"] = ! myOptions["confirmEnds"];
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_conf_phase');
	option.innerHTML = "Confirm Phase End: <b>" + (myOptions["confirmEnds"] ? " On" : " Off")+ '</b>';
}
function toggleFadeMap() 
{
	var cur = GET_MAPFADE(myOptions,mapName);
	cur = Math.round((cur*10) - 1);
	if (cur >= 11) { cur = 1;}
	if (cur <= 0) { cur = 10;}
	myOptions["fadeMap:" + mapName] = cur/10;
	if (myOptions["fadeMap:" + mapName] == myOptions["fadeMap"])
	{
		delete myOptions["fadeMap:" + mapName];
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_fade');
	option.innerHTML = "Map Opacity:  <b>" + Math.round(cur*10) + '%</b>';
	APPLY_MAPFADE(myOptions,mapName);
}

function toggleFormWidth() 
{
	var cur = GET_MINFORMWIDTH(myOptions,mapName);
	cur = cur-50;
	if (cur >= 1000) { cur = 600;}
	if (cur <= 599) { cur = 1000;}
	myOptions["MinimumFormWidth:" + mapName] = cur;
	if (myOptions["MinimumFormWidth:" + mapName] == myOptions["MinimumFormWidth"])
	{
		delete myOptions["MinimumFormWidth:" + mapName];
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_hudWidth');
	option.innerHTML = "Min HUD Width:  <b>"+cur+'</b>';
	if (myOptions["floatActions"] == "On")
	{
		setFormWidth();
	}
}

function toggleMapLeft() 
{
	var cur = GET_MAPLEFT(myOptions,mapName);
	cur--;
	if (cur >= 22) { cur = -22;}
	if (cur <= -22) { cur = 22;}
	myOptions["MapLeft:" + mapName] = cur;
	if (myOptions["MapLeft:" + mapName] == myOptions["MapLeft"])
	{
		delete myOptions["MapLeft:" + mapName];
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_align_left');
	option.innerHTML = "Map Align Left: <b>"+cur+' px</b>';
	SHIFT_MAGICMAP(myOptions,mapName);
}

function toggleMapTop() 
{
	var cur = GET_MAPTOP(myOptions,mapName);
	cur--;
	if (cur >= 22) { cur = -22;}
	if (cur <= -22) { cur = 22;}
	myOptions["MapTop:" + mapName] = cur;
	if (myOptions["MapTop:" + mapName] == myOptions["MapTop"])
	{
		delete myOptions["MapTop:" + mapName];
	}
	serialize("OPTIONS",  myOptions);
	var option = document.getElementById('menu_align_top');
	option.innerHTML = "Map Align Top: <b>"+cur+' px</b>';
	SHIFT_MAGICMAP(myOptions,mapName);
}

function createOption(id, text, func, ul, bgcolour, before)
{
	var option1 = document.createElement ('li');
	if (before)
		ul.insertBefore(option1,before.parentNode);
	else
		ul.appendChild(option1);
	var option1a = document.createElement ('a');
	this.id = option1a.id=id;
	option1.appendChild(option1a);
	option1a.href="javascript:void(0);";
	if (bgcolour)
		option1a.style.backgroundColor = bgcolour;
	this.innerHTML = option1a.innerHTML = text;
	option1a.addEventListener("click", func, false);
}

function hideMenuOption(id)
{
	var option = document.getElementById(id);
	if (option)
	{
		option.parentNode.style.display="none";
	}
}

function showMenuOption(id)
{
	var option = document.getElementById(id);
	if (option)
		option.parentNode.style.display="block";
}

function removeMenuOption(id)
{
	var option = document.getElementById(id);
	if (option)
	{
		var parentParent = option.parentNode.parentNode;
		var parent = option.parentNode;
		parent.removeChild(option);
		parentParent.removeChild(parent);
	}
}

function showSnapshotsMenu()
{
	var option = document.getElementById("menu_takesnap");
	if (option)
	{
		if (option.parentNode.style.display=="block")
		{
			hideSnapshotsMenu();
		}
		else
		{
			showMenuOption("menu_takesnap");
			showMenuOption("menu_analyse");
			showMenuOption("menu_refresh");
			loadSnapshots();
			showMenuOption("menu_delete_snaps_game");
			showMenuOption("menu_delete_snaps_all");
		}
	}
	hideMapSettingsMenu();
	hideViewSettingsMenu();
	hideConfSettingsMenu()
}

function hideSnapshotsMenu()
{
	hideMenuOption("menu_takesnap");
	hideMenuOption("menu_analyse");
	hideMenuOption("menu_refresh");
	hideMenuOption("menu_delete_snaps_game");
	hideMenuOption("menu_delete_snaps_all");
	for (var i=0;i<snapshotsMenuLength;i++)
	{
		removeMenuOption("menu_snapshot_"+i);
	}
	snapshotsMenuLength=0;
}


function showMapSettingsMenu()
{
	var option = document.getElementById("menu_fade");
	if (option)
	{
		if (option.parentNode.style.display=="block")
		{
			hideMapSettingsMenu();
		}
		else
		{
			showMenuOption("menu_fade");
			showMenuOption("menu_align_left");
			showMenuOption("menu_align_top");
		}
	}
	hideViewSettingsMenu();
	hideSnapshotsMenu();
	hideConfSettingsMenu()
}

function hideMapSettingsMenu()
{
	hideMenuOption("menu_fade");
	hideMenuOption("menu_align_left");
	hideMenuOption("menu_align_top");
}

function showViewSettingsMenu()
{
	var option = document.getElementById("menu_stats");
	if (option)
	{
		if (option.parentNode.style.display=="block")
		{
			hideViewSettingsMenu();
		}
		else
		{
			showMenuOption("menu_stats");
			showMenuOption("menu_mapInspect");
			showMenuOption("menu_textMap");
			showMenuOption("menu_clockformat");
			showMenuOption("menu_jtm");
			showMenuOption("menu_hud");
			if (myOptions["floatActions"]=="On")
				showMenuOption("menu_hudWidth");
			showMenuOption("menu_colourcode_dd");
		}
	}
	hideMapSettingsMenu();
	hideSnapshotsMenu();
	hideConfSettingsMenu()
}

function hideViewSettingsMenu()
{
	hideMenuOption("menu_stats");
	hideMenuOption("menu_mapInspect");
	hideMenuOption("menu_textMap");
	hideMenuOption("menu_clockformat");
	hideMenuOption("menu_jtm");
	hideMenuOption("menu_hud");
	hideMenuOption("menu_hudWidth");
	hideMenuOption("menu_colourcode_dd");
}

function showConfSettingsMenu()
{
	var option = document.getElementById("menu_conf_phase");
	if (option)
	{
		if (option.parentNode.style.display=="block")
		{
			hideConfSettingsMenu();
		}
		else
		{
			showMenuOption("menu_conf_phase");
			showMenuOption("menu_conf_attack");
			showMenuOption("menu_conf_deploy");
		}
	}
	hideMapSettingsMenu()
	hideViewSettingsMenu();
	hideSnapshotsMenu();
}

function hideConfSettingsMenu()
{
	hideMenuOption("menu_conf_phase");
	hideMenuOption("menu_conf_attack");
	hideMenuOption("menu_conf_deploy");
}

function showSiteSettingsMenu()
{
	var option = document.getElementById("menu_fulllog");
	if (option)
	{
		if (option.parentNode.style.display=="block")
		{
			hideSiteSettingsMenu();
		}
		else
		{
			showMenuOption("menu_fulllog");
			showMenuOption("menu_swapavas");
			showMenuOption("menu_clockformat_mygames");
		}
	}
}

function hideSiteSettingsMenu()
{
	hideMenuOption("menu_fulllog");
	hideMenuOption("menu_swapavas");
	hideMenuOption("menu_clockformat_mygames");
}

function createGameMenu()
{
    
	cc_log("Building the Settings Menu 2");          
	var ul = setupMenu();
	
	createOption("menu_sub_map", "Map Options", showMapSettingsMenu, ul);
	
	createOption("menu_fade", "Map Opacity:  <b>" + Math.round(GET_MAPFADE(myOptions,mapName)*100) + '%</b>', toggleFadeMap, ul, "#77AA77");

	createOption("menu_align_left", "Map Align Left: <b>" + Math.round(GET_MAPLEFT(myOptions,mapName)) + ' px</b>', toggleMapLeft, ul, "#77AA77");

	createOption("menu_align_top", "Map Align Top: <b>" + Math.round(GET_MAPTOP(myOptions,mapName)) + ' px</b>', toggleMapTop, ul, "#77AA77");

	createOption("menu_sub_view", "View Options", showViewSettingsMenu, ul);

	createOption("menu_stats", "Stats: <b>" + myOptions["statsMode"] + '</b>', toggleStatsMode, ul, "#77AA77");

	createOption("menu_mapInspect", "Map Inspect: <b>" + (myOptions["mapInspect"] ? " On" : " Off")+ '</b>', toggleMagicMap, ul, "#77AA77");

	createOption("menu_textMap", "Text Map: <b>" + (myOptions["textMapType"] )+ '</b>', toggleTextMap, ul, "#77AA77");

	createOption("menu_clockformat", "Clock Format: <b>" + myOptions["24hourClockFormat"] + '</b>', toggle24HourClock, ul, "#77AA77");

	createOption("menu_jtm", "Jump to Map: <b>" + (myOptions["jumptomap"] ? " On" : " Off")+ '</b>', toggleJumpToMap, ul, "#77AA77");

	createOption("menu_hud", "HUD: <b>" + myOptions["floatActions"] + '</b>', toggleFloatingActionForm, ul, "#77AA77");

	createOption("menu_hudWidth", "Min HUD Width:  <b>"+GET_MINFORMWIDTH(myOptions,mapName)+'</b>', toggleFormWidth, ul, "#77AA77");

	createOption("menu_colourcode_dd", "Colour DropDown: <b>" + myOptions["ccdd"] + '</b>', toggleColourCodeDD, ul, "#77AA77");

	createOption("menu_sub_snapshots", "Snapshots", showSnapshotsMenu, ul);

	createOption("menu_takesnap", "Take Snapshot", takeSnapshot, ul, "#77AA77");

	createOption("menu_analyse", "Analyse Snapshot", analyse, ul, "#77AA77");

	createOption("menu_refresh", "Revert To Live", 	reloadToLive, ul, "#77AA77");

	createOption("menu_delete_snaps_game", "Delete&nbsp;Game&nbsp;Snapshots", deleteGameSnaps, ul, "#77AA77");

	createOption("menu_delete_snaps_all", "Delete&nbsp;All&nbsp;Snapshots", deleteAllSnaps, ul, "#77AA77");

	createOption("menu_sub_conf", "Confirmations", showConfSettingsMenu, ul);

	createOption("menu_conf_phase", "Confirm Phase End: <b>" + (myOptions["confirmEnds"] ? " On" : " Off")+ '</b>', toggleConfirmEnds, ul, "#77AA77");

	createOption("menu_conf_attack", "Confirm AutoAttack: <b>" + (myOptions["confirmAutoAttack"] ? " On" : " Off")+ '</b>', toggleConfirmActionsAA, ul, "#77AA77");

	createOption("menu_conf_deploy", "Confirm Deploy: <b>" + (myOptions["confirmDeploy"] ? " On" : " Off")+ '</b>', toggleConfirmActionsDeploy, ul, "#77AA77");

	addSiteWideMenuOptions(ul);
}

function toggleHideMenu()
{
	if (myOptions["hideMenu"] == "Off")
	{
		myOptions["hideMenu"] = "Game";
	}
	else if (myOptions["hideMenu"] == "Game")
	{
		myOptions["hideMenu"] = "Site";
	}
	else if (myOptions["hideMenu"] == "Site")
	{
		myOptions["hideMenu"] = "On";
	}
	else
	{
		myOptions["hideMenu"] = "Off";
	}
	serialize("OPTIONS",  myOptions);
	hider = document.getElementById("menu_hider");
	hider.innerHTML = "Hide Menu: <b>" + myOptions["hideMenu"] + '</b>';
}


function toggleUpdateAvailable() 
{
	upgrader = document.getElementById("menu_upgrader");
	if (newVersionAvailable)
	{
		upgrader.innerHTML = "<span class='countdown-alert'>Update Available</span>";
	}
	else
	{
		upgrader.innerHTML = "Latest Version Installed";
	}
}


function toggle24HourClock() 
{
	clockformat = document.getElementById("menu_clockformat");
	if (!clockformat) // remember we might not be in the game menu - so we might need to get this one.
		clockformat = document.getElementById("menu_clockformat_mygames");
	if (myOptions["24hourClockFormat"] == "Off") 
	{
		myOptions["24hourClockFormat"] = "am/pm";
	} 
	else if (myOptions["24hourClockFormat"] == "am/pm") 
	{
		myOptions["24hourClockFormat"] = "24h";
	} 
	else 
	{
		myOptions["24hourClockFormat"] = "Off";
	}
	serialize("OPTIONS",  myOptions);
	clockformat.innerHTML = "Clock Format: <b> " + myOptions["24hourClockFormat"] + '</b>';
	updateMyGamesClocks();
}


function checkForUpdate() 
{
	scriptURL = 'http://www.fileden.com/files/2008/1/19/1707364/conquerclubbobsupport.txt?nocache=' + Math.random();
	GM_xmlhttpRequest({method: 'GET', url: scriptURL, onload: function(response) {
		responseArray = response.responseText.split('\n')
		var serverVersion = "1.1.1";
		for ( line in responseArray ) {
			if ( responseArray[line].match('var versionString = ') ) 
			{
				serverVersion = responseArray[line].split('"')[1]
				break;
			}
		}
		var serverVersionNumbers = serverVersion.split('.');
		var installedVersionNumbers = versionString.split('.');
		if (parseInt(serverVersionNumbers[0],10)>parseInt(installedVersionNumbers[0],10))
		{
			newVersionAvailable = true;
		}
		else if (parseInt(serverVersionNumbers[0],10)<parseInt(installedVersionNumbers[0],10))
		{
			newVersionAvailable = false;
		}
		else if (parseInt(serverVersionNumbers[1],10)>parseInt(installedVersionNumbers[1],10))
		{
			newVersionAvailable = true;
		}
		else if (parseInt(serverVersionNumbers[1],10)<parseInt(installedVersionNumbers[1],10))
		{
			newVersionAvailable = false;
		}
		else if (parseInt(serverVersionNumbers[2],10)>parseInt(installedVersionNumbers[2],10))
		{
			newVersionAvailable = true;
		}
		else
		{
			newVersionAvailable = false;
		}
		toggleUpdateAvailable();
	}})
}

function setupMenu()
{
	// setup menu headings.
	var leftBar = document.getElementById("leftColumn");

	var ul = leftBar.getElementsByTagName("ul");

	var gmMenu = document.createElement('div');
	gmMenu.id="bobmenu";
	ul[0].parentNode.appendChild(gmMenu);

	var t = document.createElement('h3');
	t.innerHTML =  "BOB Menu <span style='font-size:7pt;' ><a href='http://www.conquerclub.com/forum/viewtopic.php?t=33445'> " + versionString + "</a></span>"; 
	gmMenu.appendChild(t);


	var ul = document.createElement ('ul');
	ul.id = "bobmenuUl";
	gmMenu.appendChild(ul);
	return ul;
}

function addSiteMenuOptions(ul)
{

	createOption("menu_sub_sitemenu", "Site Options", showSiteSettingsMenu, ul);

	createOption("menu_fulllog", "Full Log: <b>" + myOptions["fulllog"] + '</b>', toggleFullLog, ul, "#77AA77");

	createOption("menu_swapavas", "Swap Avatars: <b>" + myOptions["swapavas"] + '</b>', toggleSwapAvas, ul, "#77AA77");
}

function addSiteWideMenuOptions(ul)
{

	createOption("menu_hider", "Hide Menu: <b>" + myOptions["hideMenu"] + '</b>', toggleHideMenu, ul);

	createOption("menu_help", "Help/Info", function() {showHelp(Logging)}, ul);

	createOption("menu_upgrader", "Latest Version Installed", function() {showUpgrade()}, ul);

}

function swapAvatars()
{
	var body = document.getElementById("page-body");
	var body = document.getElementById("page-body");
	if (body)
	{
		if (myOptions["swapavas"]=="On")
		{
			var avas = getElementsByClassName(body,'dl','postprofile');
			for (var i=0;i<avas.length;i++)
			{
				avas[i].setAttribute("style","float:left;border-right:1px solid #FFFFFF;border-left:0px solid #FFFFFF;");//background-image:url('./styles/prosilver/imageset/en/icon_user_online.gif');background-position:100% 0pt;background-repeat:no-repeat");
			}
			if (avas.length>0)
			{
				var posts = getElementsByClassName(body,'div','postbody');
				for (var i=0;i<posts.length;i++)
				{
					posts[i].setAttribute("style","float:right");
				}
				var online = getElementsByClassName(body,'div','online');
				for (var i=0;i<online.length;i++)
				{
					online[i].setAttribute("style","background-position:100% 17pt");
				}
			}
		}
		else
		{
			var avas = getElementsByClassName(body,'dl','postprofile');
			for (var i=0;i<avas.length;i++)
			{
				avas[i].setAttribute("style","float:right;border-left:1px solid #FFFFFF;border-right:0px solid #FFFFFF");
			}
			if (avas.length>0)
			{
				var posts = getElementsByClassName(body,'div','postbody');
				for (var i=0;i<posts.length;i++)
				{
					posts[i].setAttribute("style","float:left");
				}
				var online = getElementsByClassName(body,'div','online');
				for (var i=0;i<online.length;i++)
				{
					online[i].setAttribute("style","background-position:100% 0pt");
				}
			}
		}
	}
}

// function to change game links to load full log.
function updateGameLinks()
{
	if (myOptions["fulllog"]=="On")
	{
		var hrefs = document.getElementById('middleColumn').getElementsByTagName("a");
		for (var i=0;i<hrefs.length;i++)
		{
			if (hrefs[i].href.has("game.php"))
			{
				hrefs[i].href += "&full_log=Y";
			}
		}
	}
}

function updateMyGamesClocks()
{
	if (location.href.indexOf("mygames")>=0 || location.href.indexOf("mode=next")>=0) // if in mygames...
	{
		if (location.href.indexOf("mygames2")>=0 || location.href.indexOf("mygames3")>=0 || location.href.indexOf("mygames4")>=0) // but if not in active
			return false;
		var middle = document.getElementById('middleColumn');
		var evens = getElementsByClassName(middle,"tr","even",true);
		updateMyGamesClock(evens);
		var odds = getElementsByClassName(middle,"tr","odd",true);
		updateMyGamesClock(odds);
		return true;
	}
	else
		return false;
}

function updateMyGamesClock(elements)
{
	for (i=0;i<elements.length;i++)
	{
		var tr = elements[i];
		var tds = tr.childNodes;
		var tds = tr.childNodes;
		var td = tds[9];
		var hrsidx = td.innerHTML.indexOf("hrs");
		var bridx = td.innerHTML.lastIndexOf("<br>");
		time = td.innerHTML.substring(hrsidx-2);
		time = time.split(" ");
		finish = calcEndOfTurnTime(myOptions["24hourClockFormat"], parseInt(time[0],10), parseInt(time[1],10));
		if (bridx<hrsidx)
			td.innerHTML += "<br/>"+finish;
		else
			td.innerHTML = td.innerHTML.substring(0,bridx) + "<br/>" + finish;
	}


}

function showHelp(tlog) 
{
	var win = window.open("http://www.hometag.net/downloads/CC/BOB/help.htm","bobHelp","height=600, width=600, toolbar=no, scrollbars=yes, menubar=no");
	win.focus();
}

function showUpgrade() 
{
	var win = window.open("http://userscripts.org/scripts/source/13076.user.js","bobUpgrade","height=1, width=1, toolbar=no, scrollbars=no, menubar=no, resizable=no");
	win.focus();
	win.close();
}

function cc_log (m) 
{
	Logging += Math.round((new Date()).getTime()/1000)-startLogTime + ":" + m + "<br />" 
}

// Altered to allow partial matches... player matches player1 ... 2 etc.
function getElementsByClassName(oElm, strTagName, strClassName, exact)
{
        var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
        var arrReturnElements = new Array();
        strClassName = strClassName.replace(/\-/g, "\\-");
        var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s)");
        var oElement;
        for(var i=0; i<arrElements.length; i++){
            oElement = arrElements[i];
	        if (exact)
	        {
		    if(oElement.className==strClassName){
			arrReturnElements.push(oElement);
		    }
	        }
		else
		{
		    if(oElement.className.has(strClassName)){
			arrReturnElements.push(oElement);
		    }
		}
        }
        return (arrReturnElements)
}

//mfontlans zslash function
function zslash(svalue, iwidth)
{
   var szero = String(svalue);
   var ch = szero.substr(0,1);
   while (ch == ' ')
   {
      szero = szero.substr(1, szero.length);
      ch = szero.substr(0,1);
   }
   ch = szero.substr(szero.length - 1, szero.length);
   while (ch == ' ')
   {
      szero = szero.substr(0, szero.length - 1);
   ch = szero.substr(szero.length - 1, szero.length);
   }
   
   var i=0;
   for (i=0; i < (iwidth - szero.length); i++)
   {
      szero = '0' + szero;
   }   

   return szero;
} 
    
function countDown()
{
	var clock = document.getElementById('clock');
	var clockFormat = myOptions['24hourClockFormat'];
	
        --seconds1;
        if(seconds1 < 0 ){
            --minutes1;
            if( minutes1 < 0 ){
                --hours1;
                if( hours1 < 0 ){
                    hours1 = 0;
                    if( minutes1 <= 0 && seconds1 <= 0 ){
                        clearInterval(clockInterval);//No more counting down
                        //No weird negative #s
                        minutes1= 0;
                        seconds1 = 0;
                        return;
                    }
                }
                minutes1 = 59;
            }
            seconds1 = 59;
        }
//	clock.innerHTML = hours1+'hrs '+minutes1+'min '+seconds1+'sec';

	var clockhtml = "";

	//mfontlans clock fix.
	if (((hours1==0) && (minutes1<10) && !unsafeWindow.speed) || (unsafeWindow.speed && minutes1<1))
		clockhtml += '<span class="countdown-alert">';
		
	clockhtml +=  zslash(hours1, 2) + 'hrs ' + zslash(minutes1, 2) + 'min ' + zslash(seconds1, 2) + 'sec';
	
	if (((hours1==0) && (minutes1<10) && !unsafeWindow.speed) || (unsafeWindow.speed && minutes1<1))
		clockhtml += "</span>";
		
        if (clockFormat !="Off") 
	{
             clockhtml += ' [' + calcEndOfTurnTime(clockFormat,hours1,minutes1)+ "]";
        }
        clock.innerHTML = clockhtml;


   // yowsers clock fix
/*   if( hours1 < 10)
   {
      clock.innerHTML = '0'+hours1+'hrs ';
   }
   else
   {
      clock.innerHTML = hours1+'hrs ';
   }
   if( minutes1 < 10)
   {
      clock.innerHTML = clock.innerHTML+'0'+minutes1+'min ';
   }
   else
   {
      clock.innerHTML = clock.innerHTML+minutes1+'min ';
   }
   if( seconds1 < 10)
   {
      clock.innerHTML = clock.innerHTML+'0'+seconds1+'sec';
   }
   else
   {
      clock.innerHTML = clock.innerHTML+seconds1+'sec';
   } */
}

function calcEndOfTurnTime(clockFormat, h, m)
{
	if (clockFormat=="Off")
		return "";
        var day = ' @ ';
        var ampm = '';

        var currentTime = new Date();
        var hours = currentTime.getHours();
        var minutes = currentTime.getMinutes();

        minutes = (minutes + m);
        if (minutes >= 60) {
                hours = hours + 1;
                minutes = minutes - 60;
            }

        hours = (hours + h);
        if (hours >= 24)
            {
                day = "Tomorrow @ ";
                hours = hours - 24
            }
        else
        {
                day = "Today @ ";
        }

	if (clockFormat == "am/pm") 
	{
		ampm = " am";
                if (hours >= 12)
                {
                    ampm = " pm";
                    hours = hours - 12;
                }
                if (hours == 0) hours = 12;
	}
	var timeDisplay = day + "<b>" + zslash(hours, 2) + ":" + zslash(minutes, 2) + ampm + "</b>";
	return timeDisplay;
}


function calcRedemption()
{
        if( m_bonusCards == eBonusCards.ESCALATING )
	{
		if( num_turnins < 5 ) 
			return num_turnins * 2 + 4;
		else 
			return num_turnins * 5 - 10;
        } 
	else if( m_bonusCards == eBonusCards.FLATRATE) 
		return 7;
        return 0; //no cards
}

function calcArmiesNextTurn(countries)
{
	var ret = 0; 
	if (reinforcementsArray.length==0) // old school.
	{
		if(countries < 12 ) 
			return 3; 
		ret = Math.floor(countries/3);
	}
	else // new territory array stuff.
	{
		var armiesAwarded = 0;
		for (i=0;i<reinforcementsArray.length;i++)
		{
			var lower = reinforcementsArray[i]._lower;
			var upper = reinforcementsArray[i]._upper;
			var divisor = reinforcementsArray[i]._divisor;
			if (countries>=lower)
			{
				armiesAwarded += Math.floor(  (Math.min(countries, upper)-(lower-1))/divisor);
			}
		}
		ret = Math.max(armiesAwarded,minimumReinforcements);
	}
	return ret;
}

//---- Returns probability of a tunin - http://www.kent.ac.uk/IMS/personal/odl/riskfaq.htm#3.5 ----
function getTurnInP(num_cards)
{
        if( num_cards < 3 ) return 0;
        if( num_cards > 4 ) return 1;
        if( num_cards == 3 ) return 0.3341;
        return 0.778; // has 4 cards
}

// START TAHITIWAHINI ARMIES FROM CARDS CALCULATIONS
// The following functions are derived from the calculations at:
// http://www.conquerclub.com/forum/viewtopic.php?t=15620
    
// Returns the probability of having a set 
// when holding the given number of cards.
function getSetProbability(cards) 
{
        if (cards < 3) return 0;
        if (cards == 3) return 0.333333;
        if (cards == 4) return 0.777778;
        if (cards >= 5) return 1;
        return -1;
}
    
    // Returns the number of armies expected from cashing in
    // a set when holding the given number of cards.
function getArmiesFromCardSet(cards) 
{
        if (m_bonusCards != eBonusCards.FLATRATE) {
            return getSetProbability(cards) * calcRedemption();
        } else {
            if (cards < 3) return 0;
            if (cards == 3) return 2.888889;
            if (cards == 4) return 5.333333;
            if (cards >= 5) return 7.333333;
            return -1;
        }
}  
    
// Returns the number of armies received from owning countries.
function getArmiesFromCountries(countries, continentBonus, missedTurns) 
{
        return (calcArmiesNextTurn(countries) + continentBonus) * (missedTurns + 1);
}
    
// Returns the estimated number of armies due for cashing in a set 
// of cards.
function getEstimatedArmiesFromCards(cards, countries, totalCountries) 
{
        return getArmiesFromCardSet(cards) + (6 * getSetProbability(cards) * (countries / totalCountries));
}

    // Returns the total number of armies expected for the next turn.
function getTotalExpectedArmies(countries, continentBonus, missedTurns, cards, totalCountries) 
{
        return getArmiesFromCountries(countries, continentBonus, missedTurns) + getEstimatedArmiesFromCards(cards, countries, totalCountries);
}

// Returns the calculated strength of a players position rounded to the 
// nearest hundreth.
function getStrength(currentArmies, expectedArmies, countries) 
{
        return Math.round ((currentArmies + expectedArmies - ((2 / 3) * countries)) * 100) / 100;
}
    
// END TAHITIWAHINI ARMIES FROM CARDS CALCULATIONS

function GET_MAPFADE(OPTIONS,mapName) 
{
	var fade = 1;
	if (typeof(OPTIONS["fadeMap:"+mapName])=="undefined") 
        {
            fade = OPTIONS["fadeMap"];
        }
        else
        {
            fade = OPTIONS["fadeMap:" + mapName];
        }
	// force Opacity to not be 0.
	if (fade==0)
	{
		return 1;
	}
	else
	{
		return fade;
	}
}

function APPLY_MAPFADE(OPTIONS,mapName) 
{ 
        var fm = document.getElementById("outer-map");
        fm.style.opacity = GET_MAPFADE(OPTIONS,mapName);
}   

function APPLY_TEXTMAP(OPTIONS) 
{
	if (OPTIONS['textMapType']!="Off")
	{
		if (OPTIONS['textMapType']=="Standard") 
		{ 
			textMap.innerHTML = "<h3>Text Map</h3><table align=center style='width:100%;border:1px solid #FFF;background:#eee;' rules=rows >" + txtMapSmallHtml + "</table>";
		}
		else 
		{
			textMap.innerHTML = txtMapHtml;
		}
	}
	else
	{
		textMap.innerHTML = "";
	}
}


function teamNumber(pid) 
{
	// OK game type = doubles
        //  0 = 0, 1&2 = 1, 3&4 = 2, 5&6 = 3 7&8 = 4
        // game type = triples
        //  0 = 0, 1&2&3 = 1, 4&5&6 = 2
        // Other Games Team=PID
        var tid = pid;
        
        if (pid==UID)
        	return 0;
        
        if (pid!=0 && m_gameType == eGameType.DOUBLES) {
            if (pid==1 || pid == 2) {
                tid = 1;
            }else if (pid==3 || pid == 4) {
                tid = 2;
            }else if ((pid==5 || pid == 6) && num_players>5) {
                tid = 3;
            }else if (num_players>7) {
                tid = 4;
            }
        }
        else if (pid!=0 && m_gameType == eGameType.TRIPLES) {
            if (pid==1 || pid == 2 || pid == 3) {
                tid = 1;
            }else {
                tid = 2;
            }
        } 
        else if (pid!=0 && m_gameType == eGameType.QUADRUPLES) {
            if (pid==1 || pid == 2 || pid == 3 || pid == 4) {
                tid = 1;
            }else {
                tid = 2;
            }
        } 
        return tid;
}
    
function isTeamGame() 
{
	return m_gameType == eGameType.DOUBLES || m_gameType == eGameType.TRIPLES || m_gameType == eGameType.QUADRUPLES;
}


function makeTableCellTextWorker(bEliminated,pid, strText,bwrap) 
{
	if (pid==UID)
		pid=0;
        return "<td" + (bwrap?"":" nowrap") +"><span " + (bEliminated ? "class=eliminated" : "" ) + "><span class='playerBG"+ pid +"'>"+  strText +  " </span></span></td>\n" 
}

function makeTableCellText(bEliminated,pid, strText,bwrap) 
{
        return makeTableCellTextWorker(bEliminated,pid, strText,false) ;
}

function makeTableCellTextWrap(bEliminated,pid, strText) 
{
        return makeTableCellTextWorker(bEliminated,pid, strText,true) ;
}

function APPLY_STATS(OPTIONS) 
{
    
        if (OPTIONS["statsMode"] == "Off") {
            stats.innerHTML = "";
        }
        else if (OPTIONS["statsMode"] == "Standard") {
            stats.innerHTML = statsStr2;
        }
        else // Extended
        {
            stats.innerHTML = statsStr;
        }
}



// Static enums - now globalised
//Game Enumerations
var eGameType = { TERMINATOR:0, STANDARD:1, DOUBLES:2, TRIPLES:3, QUADRUPLES:4, ASSASSIN:5 }
var ePlayOrder = { NDTFREESTYLE: 0, FREESTYLE:1, SEQUENTIAL:2 }
var eBonusCards = { NOCARDS:0, FLATRATE:1, ESCALATING:2 }

// globalise variable to easily function out calls.
var m_gameType;
var m_bonusCards;
var fog = false;
var logDiv = document.getElementById('log');
var rightside = document.getElementById('right_hand_side');
var dashboard = document.getElementById('dashboard');
var map = document.getElementById('outer-map');
var armies = document.getElementById('armies');
var colourBlind;
var newVersionAvailable = false;
var minimumReinforcements = 3;
var siblings;

//---- Prototyping ----
String.prototype.has = function(key) { return this.indexOf(key) > -1; }
String.prototype.makeID = function() { return this.replace(/ /g,"_").replace(/'/g,"_").replace(/#/g,"_").replace(/\?/g,"_"); }
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); };

String.prototype.normiliseSpaces = function() { return this.replace(/  /g," ").trim(); }

var jtm = function jtm() {window.location.hash="map-cell";}


//-------------------------------------------------------------------------
//    VARIABLE DECLARATIONS
//-------------------------------------------------------------------------

//---- Gameplay ----
var rounds = 0;
var stored_rounds = 0;
var num_turnins = 0;
var stored_num_turnins = 0;
var stored_skipped = new Array();
var stored_countries = new Array();
var stored_terminator_summary;
var TerminatorSummary = "";
var stored_territories = new Array();
var stored_last_bonus = new Array();
var num_players = 0;
var m_playOrder;
var RedemptionValue;
var redemption;
var pIndxs;

var smallwidth;
var smallheight;
var largewidth;
var largeheight;

//---- Player ----
var NID = 0; // Neutral ID
var UID = 0; // Unknown ID <-- set to 0 here to ensure a value always set
var pl_Colors = new Array("666","f00","090","00f","cc0","0cc","f0f");//Player Colors
    
var pl_cbIDs = new Array("n","r","g","b","y","t","p"); //Color Blind Identifiers

//---- Misc ----
var i;
var tmp;
var re;
var pid; // player identifier
var name; // tmp name

var mapName;
var mapSize;

var textMap;
var txtMapHtml;
var txtMapSmallHtml;
var txtMapSmallHtml2;
var txtMapSmallOwner;
var bDone;


var RedemptionValue=0;
var stats;
var statsStr = "";
var statsStr2 = "";

var totalArmies = 0;
var totalCountries = 0;
var totalStartCountries = 0;

//---- Clock ----
var today = new Date();
var time = new Array();// { hh, mm, ss }
var timeStr;
var timeLocStr;
var timeLoc;//location of the time
var timeindexOffset;//location of the time + the index ( hr, min, or sec )
var timeWIDTH = 18;
var clock;
var clockInterval;
var hours1;
var minutes1;
var seconds1;
var colourblind = unsafeWindow.colourblind;
var snapshotsMenuLength = 0;
var currentSnapshot = -1;
var currentSnapshotSelectStringStart = "<b>";
var currentSnapshotSelectString = "</b>";
var currentSnapshotArray = new Array();
var liveSnapshotArray = new Array();
var showDeleteAll = false;

// this function is run ONCE on initial INIT of the script.
function gm_ConquerClubGame(OPTIONS)
{
    cc_log("Starting");

//    ---- Check for Required Components ----

    //If we cannot find any of the following then we're not in a game.
    if( !( logDiv && rightside && dashboard && armies) ) 
    {
	var centre = document.getElementById("middleColumn");
	if (centre) // check center exists - this may be a page within a page.
	{
		var leftBar = document.getElementById("leftColumn");
		var ul = leftBar.getElementsByTagName("ul");
		if (ul[0]) // check ul exists - user may not be logged in.
		{
			prepareMenuHider();

			var ul = setupMenu();
			addSiteMenuOptions(ul);
			var myGames = updateMyGamesClocks();
			if (myGames)
				createOption("menu_clockformat_mygames", "Clock Format: <b>" + myOptions["24hourClockFormat"] + '</b>', toggle24HourClock, ul, '#77AA77');
			addSiteWideMenuOptions(ul);
			updateGameLinks();
			swapAvatars();
			hideMenu();
			checkForUpdate();
		}
	}
	stopWaiting();
    	return;
    }
    customStartWaiting("Initializing BOB");

    timeLocStr = rightside.innerHTML.has('<span class="countdown-alert">')?'<h4 id="time-remaining">Time Remaining</h4>\n<span id="clock">\n<span class="countdown-alert">':'<h4 id="time-remaining">Time Remaining</h4>\n<span id="clock">';

    //-------------------------------------------------------------------------
    //    INIT
    //-------------------------------------------------------------------------


//    ---- Start Clock ----
/*    tmp = rightside.innerHTML.indexOf(timeLocStr);//to make sure there is a clock.
    if( tmp > -1 ){
        timeLoc = tmp + timeLocStr.length ;
        tmp = rightside.innerHTML;
        timeStr = tmp.substring(timeLoc,timeLoc + timeWIDTH);
        time = timeStr.split(/hrs\n|min\n|sec\n/);

        var currentTime = new Date();
        var hours = currentTime.getHours();
        var minutes = currentTime.getMinutes();
        var day = ' @ ';
        var ampm = ' '; 
         
        minutes = (minutes + parseInt(time[1]));
        if (minutes >= 60) {
                hours = hours + 1;
                minutes = minutes - 60;
            }
        
        if (time[0][0] == '0')
        {
            time[0] = time[0][1];
        }
        hours = (hours + parseInt(time[0]));
        if (hours >= 24) 
            {
                day = "tomorrow @ ";
                hours = hours - 24
            }
            if (OPTIONS['24hourClockFormat']=="am/pm") {
                ampm = " am";
                if (hours >= 12)
                {
                    ampm = " pm";
                    hours = hours - 12;
                } 
                if (hours == 0) hours = 12; 
            }
        else
        {
            if (hours < 10)
            {
                hours = "0" + hours;
            }
        }
        
        if (minutes < 10)
            minutes = "0" + minutes;
        
        if (OPTIONS['24hourClockFormat']!="Off") {
            clock =  day + "<b>" + hours + ":" + minutes + ampm + " " + "</b>"
        }
        else
        {
            clock = ""
        }
        hours1 = parseInt(time[0]);
        minutes1 = parseInt(time[1]);
        seconds1 = parseInt(time[2]);

        clockInterval = window.setInterval(countDown,1000);
    }*/

    // Yowsers clock fix
    tmp = rightside.innerHTML.indexOf(timeLocStr);//to make sure there is a clock.
    if( tmp > -1 ){
        timeLoc = tmp + timeLocStr.length ;
        tmp = rightside.innerHTML;
        timeStr = tmp.substring(timeLoc,timeLoc + timeWIDTH);
       
        time = timeStr.split(/hrs\n|min\n|sec\n/);

        var currentTime = new Date();
        var hours = currentTime.getHours();
        var minutes = currentTime.getMinutes();
        var day = ' @ ';
        var ampm = ' ';
         
        minutes = (minutes + parseInt(time[1],10));
        if (minutes >= 60) {
                hours = hours + 1;
                minutes = minutes - 60;
            }
       
        if (time[0][0] == '0')
        {
            time[0] = time[0][1];
        }
        hours = (hours + parseInt(time[0],10));
        if (hours >= 24)
            {
                day = "tomorrow @ ";
                hours = hours - 24
            }
            if (OPTIONS['24hourClockFormat']=="am/pm") {
                ampm = " am";
                if (hours >= 12)
                {
                    ampm = " pm";
                    hours = hours - 12;
                }
                if (hours == 0) hours = 12;
            }
        else
        {
            if (hours < 10)
            {
                hours = "0" + hours;
            }
        }
       
        if (minutes < 10)
            minutes = "0" + minutes;
       
        if (OPTIONS['24hourClockFormat']!="Off") {
            clock =  day + "<b>" + hours + ":" + minutes + ampm + " " + "</b>"
        }
        else
        {
            clock = ""
        }
        hours1 = parseInt(time[0],10);
        minutes1 = parseInt(time[1],10);
        seconds1 = parseInt(time[2],10);

        clockInterval = window.setInterval(countDown,1000);
    } 

    // is this game with fog of war on?
    if (dashboard.innerHTML.indexOf("Fog of War: <b>Yes")!=-1)
    {
	fog = true;
    }


    getCardType();


//    ---- Create Divisions ----
    stats = document.createElement('div');
    stats.id="statsTable";
    dashboard.parentNode.insertBefore(stats, logDiv.previousSibling.previousSibling);
    stats.style.margin = '10px 0 0 0';

//     Create text map 
    textMap = document.createElement('div');
    textMap.id="textMap";
    dashboard.parentNode.insertBefore(textMap, logDiv.previousSibling.previousSibling);
    textMap.style.margin = '10px 0 0 0';

    if (document.getElementById("action-form"))
    	siblings = stats.previousSibling.previousSibling.previousSibling.previousSibling;
    else
    	siblings = stats.previousSibling.previousSibling;

    var mapInspectDiv = document.createElement('div');
    mapInspectDiv.id="mapinspect";
    dashboard.parentNode.insertBefore(mapInspectDiv, siblings);
    mapInspectDiv.style.backgroundColor = "#EEEEEE";

    redemption = document.createElement('div');
    redemption.id="redemption";
    dashboard.parentNode.insertBefore(redemption, siblings);
    redemption.style.backgroundColor = "#EEEEEE";


    var chatDiv = document.getElementById("chat");

//     Create text map 
    termWrapper = document.createElement('div');
    termWrapper.id="termWrapper";
    dashboard.parentNode.insertBefore(termWrapper, chatDiv.previousSibling.previousSibling);
    termWrapper.style.margin = '10px 0 0 0';
	if (m_gameType == eGameType.TERMINATOR) 
	{
		termWrapper.innerHTML = "<h3>Terminator Points Summary</h3>"
	}
	else
	{
		termWrapper.innerHTML += "<h3>Elimination Summary</h3>"
	}


    if (OPTIONS["floatActions"] == "On")
    {
	var actionForm = document.getElementById('action-form');
	if (actionForm)
	{
		actionForm.style.position='fixed';
		actionForm.style.bottom=0;
		actionForm.style.zIndex=2;
		var wrapperDiv = document.createElement('div');
		wrapperDiv.id="actionWrapper";
		if (document.getElementById('from_country'))
			wrapperDiv.style.paddingTop="22px";
		else
			wrapperDiv.style.paddingTop="0px";
		var mapInspect = document.getElementById('mapinspect');
		wrapperDiv.appendChild(mapInspect);
		var cards = document.getElementById('cards');
		if (cards)
		{
			cards = cards.parentNode.parentNode;
			cards.style.backgroundColor="#EEEEEE";
			wrapperDiv.appendChild(cards);
		}
		actionForm.childNodes[1].appendChild(wrapperDiv);
		setFormWidth();
	}
	var outerRolls = document.getElementById('rolls');
	if (outerRolls)
	{
		outerRolls.style.position='fixed';
		outerRolls.style.backgroundColor="#EEEEEE";
		outerRolls.style.top=0;
		outerRolls.style.zIndex=1;
	}
    }


//    ---- Get Game Modes ----
    if( dashboard.innerHTML.has("Sequential") ) 
        {
            m_playOrder = ePlayOrder.SEQUENTIAL;
        }
    else 
        {
            if( dashboard.innerHTML.has("Freestyle (no double turns)") )
                m_playOrder = ePlayOrder.NDTFREESTYLE;
            else
                m_playOrder = ePlayOrder.FREESTYLE;
        }

//    ---- Get Game Type ----
    if (dashboard.innerHTML.has("Doubles") ) m_gameType = eGameType.DOUBLES;
    else if (dashboard.innerHTML.has("Triples") ) m_gameType = eGameType.TRIPLES;
    else if (dashboard.innerHTML.has("Quadruples") ||  dashboard.innerHTML.has("Game Type: <b></b>")) m_gameType = eGameType.QUADRUPLES;
    else if (dashboard.innerHTML.has("Terminator") ) m_gameType = eGameType.TERMINATOR;
    else if (dashboard.innerHTML.has("Assassin") ) m_gameType = eGameType.ASSASSIN;
    else m_gameType = eGameType.STANDARD;


//     --- Add Styles ---
/*
Number Colors
#FFFFFF: White (Neutral)
#FF0000: Red (Both Same)
#0000FF: Blue (Both Same)
#009A04: Green (Both Same)
#FFFF00: Yellow (Bright)
#FF00FF: Magenta/pink (Both Same)
#00FFFF: Cyan (Bright)
#7F7F7F: Gray (Both Same)
#FF9922: Orange (Both Same)

Log Colors
#000000: Black (Neutral) <- Neutral has always been black in the logs!
#FF0000: Red (Both Same)
#0000FF: Blue (Both Same)
#009A04: Green (Both Same)
#CCCC00: Yellow (Muted)
#FF00FF: Magenta/pink (Both Same)
#00CCCC: Cyan (Muted)
#7F7F7F: Gray (Both Same)
#FF9922: Orange (Both Same) 
*/


// Colour Defs
// Number
var col0 = new Array();
col0[0] = "#FFFFFF"; // neutral
col0[1] = "#FF0000";
col0[2] = "#009A04";
col0[3] = "#0000FF";
col0[4] = "#FFFF00";
col0[5] = "#FF00FF";
col0[6] = "#00FFFF";
col0[7] = "#FF9922";
col0[8] = "#7F7F7F";
col0[9] = "#000000"; // BR colour
//Log
var col1 = new Array();
col1[0] = "#000000";
col1[1] = "#FF0000";
col1[2] = "#009A04";
col1[3] = "#0000FF";
col1[4] = "#DDDD00";
col1[5] = "#FF00FF";
col1[6] = "#00CCCC";
col1[7] = "#FF9922";
col1[8] = "#7F7F7F";
col1[9] = "#BBBBBB"; // BR colour

GM_addStyle(' #outer-map { position:relative;} ' +
                ' #inner-map img { position:absolute;} ' +
                ' #summary {height: 150px;overflow: auto;background-color: #eee; margin:10px 0 0 0;} ' +
                ' #magicmap div   { height: 18px; height: 100%; width: 100%; position:absolute; opacity:0.0;} ' +

                ' #magicmap .hplayer0  {  opacity:1.5; border:thick solid ' + col0[0] + ';} ' +
                ' #magicmap .hplayer1  {  opacity:1.5; border:thick solid ' + col0[1] + ';} ' +
                ' #magicmap .hplayer2  {  opacity:1.5; border:thick solid ' + col0[2] + ';} ' +
                ' #magicmap .hplayer3  {  opacity:1.5; border:thick solid ' + col0[3] + ';} ' +
                ' #magicmap .hplayer4  {  opacity:1.5; border:thick solid ' + col0[4] + ';} ' +
                ' #magicmap .hplayer5  {  opacity:1.5; border:thick solid ' + col0[5] + ';} ' +
                ' #magicmap .hplayer6  {  opacity:1.5; border:thick solid ' + col0[6] + ';} ' +
                ' #magicmap .hplayer7  {  opacity:1.5; border:thick solid ' + col0[7] + ';} ' +
                ' #magicmap .hplayer8  {  opacity:1.5; border:thick solid ' + col0[8] + ';} ' +


                ' #magicmap .lplayer0  {  opacity:0.0; border:thick solid ' + col0[0] + ';} ' +
                ' #magicmap .lplayer1  {  opacity:0.0; border:thick solid ' + col0[1] + ';} ' +
                ' #magicmap .lplayer2  {  opacity:0.0; border:thick solid ' + col0[2] + ';} ' +
                ' #magicmap .lplayer3  {  opacity:0.0; border:thick solid ' + col0[3] + ';} ' +
                ' #magicmap .lplayer4  {  opacity:0.0; border:thick solid ' + col0[4] + ';} ' +
                ' #magicmap .lplayer5  {  opacity:0.0; border:thick solid ' + col0[5] + ';} ' +
                ' #magicmap .lplayer6  {  opacity:0.0; border:thick solid ' + col0[6] + ';} ' +
                ' #magicmap .lplayer7  {  opacity:0.0; border:thick solid ' + col0[7] + ';} ' +
                ' #magicmap .lplayer8  {  opacity:0.0; border:thick solid ' + col0[8] + ';} ' +


                ' #magicmap .iplayer0  {  opacity:0.8; border:thick dashed ' + col0[0] + ';} ' +
                ' #magicmap .iplayer1  {  opacity:0.8; border:thick dashed ' + col0[1] + ';} ' +
                ' #magicmap .iplayer2  {  opacity:0.8; border:thick dashed ' + col0[2] + ';} ' +
                ' #magicmap .iplayer3  {  opacity:0.8; border:thick dashed ' + col0[3] + ';} ' +
                ' #magicmap .iplayer4  {  opacity:0.8; border:thick dashed ' + col0[4] + ';} ' +
                ' #magicmap .iplayer5  {  opacity:0.8; border:thick dashed ' + col0[5] + ';} ' +
                ' #magicmap .iplayer6  {  opacity:0.8; border:thick dashed ' + col0[6] + ';} ' +
                ' #magicmap .iplayer7  {  opacity:0.8; border:thick dashed ' + col0[7] + ';} ' +
                ' #magicmap .iplayer8  {  opacity:0.8; border:thick dashed ' + col0[8] + ';} ' +

                ' #magicmap .mplayer0  {  opacity:0.0; border:thick solid ' + col0[0] + ';} ' +
                ' #magicmap .mplayer1  {  opacity:0.0; border:thick solid ' + col0[1] + ';} ' +
                ' #magicmap .mplayer2  {  opacity:0.0; border:thick solid ' + col0[2] + ';} ' +
                ' #magicmap .mplayer3  {  opacity:0.0; border:thick solid ' + col0[3] + ';} ' +
                ' #magicmap .mplayer4  {  opacity:0.0; border:thick solid ' + col0[4] + ';} ' +
                ' #magicmap .mplayer5  {  opacity:0.0; border:thick solid ' + col0[5] + ';} ' +
                ' #magicmap .mplayer6  {  opacity:0.0; border:thick solid ' + col0[6] + ';} ' +
                ' #magicmap .mplayer7  {  opacity:0.0; border:thick solid ' + col0[7] + ';} ' +
                ' #magicmap .mplayer8  {  opacity:0.0; border:thick solid ' + col0[8] + ';} ' +


                ' #magicmap .jplayer0  {  opacity:10.8; border:thick dashed  ' + col0[0] + ';} ' +
                ' #magicmap .jplayer1  {  opacity:10.8; border:thick dashed  ' + col0[1] + ';} ' +
                ' #magicmap .jplayer2  {  opacity:10.8; border:thick dashed  ' + col0[2] + ';} ' +
                ' #magicmap .jplayer3  {  opacity:10.8; border:thick dashed  ' + col0[3] + ';} ' +
                ' #magicmap .jplayer4  {  opacity:10.8; border:thick dashed  ' + col0[4] + ';} ' +
                ' #magicmap .jplayer5  {  opacity:10.8; border:thick dashed  ' + col0[5] + ';} ' +
                ' #magicmap .jplayer6  {  opacity:10.8; border:thick dashed  ' + col0[6] + ';} ' +
                ' #magicmap .jplayer7  {  opacity:10.8; border:thick dashed  ' + col0[7] + ';} ' +
                ' #magicmap .jplayer8  {  opacity:10.8; border:thick dashed  ' + col0[8] + ';} ' +

                ' #magicmap .nplayer0  {  opacity:0.0; border:thick solid ' + col0[0] + ';} ' +
                ' #magicmap .nplayer1  {  opacity:0.0; border:thick solid ' + col0[1] + ';} ' +
                ' #magicmap .nplayer2  {  opacity:0.0; border:thick solid ' + col0[2] + ';} ' +
                ' #magicmap .nplayer3  {  opacity:0.0; border:thick solid ' + col0[3] + ';} ' +
                ' #magicmap .nplayer4  {  opacity:0.0; border:thick solid ' + col0[4] + ';} ' +
                ' #magicmap .nplayer5  {  opacity:0.0; border:thick solid ' + col0[5] + ';} ' +
                ' #magicmap .nplayer6  {  opacity:0.0; border:thick solid ' + col0[6] + ';} ' +
                ' #magicmap .nplayer7  {  opacity:0.0; border:thick solid ' + col0[7] + ';} ' +
                ' #magicmap .nplayer8  {  opacity:0.0; border:thick solid ' + col0[8] + ';} ' +

                ' .playerBG0 { color: ' + col1[0] + '; } ' +
                ' .playerBG1 { color: ' + col1[1] + '; font-weight: bold} ' +
                ' .playerBG2 { color: ' + col1[2] + '; font-weight: bold} ' +
                ' .playerBG3 { color: ' + col1[3] + '; font-weight: bold} ' +
                ' .playerBG4 { color: ' + col1[4] + '; font-weight: bold} ' +
                ' .playerBG5 { color: ' + col1[5] + '; font-weight: bold} ' +
                ' .playerBG6 { color: ' + col1[6] + '; font-weight: bold} ' +
                ' .playerBG7 { color: ' + col1[7] + '; font-weight: bold} ' +
                ' .playerBG8 { color: ' + col1[8] + '; font-weight: bold} ' +

                ' .playerBGDD0 { background-color: ' + col0[0] + '; } ' +
                ' .playerBGDD1 { background-color: ' + col1[1] + '; } ' +
                ' .playerBGDD2 { background-color: ' + col1[2] + '; } ' +
                ' .playerBGDD3 { background-color: ' + col1[3] + '; } ' +
                ' .playerBGDD4 { background-color: ' + col1[4] + '; } ' +
                ' .playerBGDD5 { background-color: ' + col1[5] + '; } ' +
                ' .playerBGDD6 { background-color: ' + col1[6] + '; } ' +
                ' .playerBGDD7 { background-color: ' + col1[7] + '; } ' +
                ' .playerBGDD8 { background-color: ' + col1[8] + '; } '); 

//    ---- Get Player Names ----
    cc_log("Player IDs");
    playersArray["Neutral"] = new Player("Neutral",NID,pl_Colors[NID]);
   
    pIndxs = getElementsByClassName(rightside,"span","player");
    for( i in pIndxs )
    {
        if( pIndxs[i].innerHTML ) 
        {
            playersArray[pIndxs[i].innerHTML] = new Player(pIndxs[i],++num_players,pl_Colors[i]);
        }
	if (i>7) // create styles for this player. (BR Coding!)
	{
		var num = parseInt(i,10)+1;
		var styl = ' #magicmap .hplayer'+num+'  {  opacity:1.5; border:thick solid ' + col0[9] + ';} ' +
				' #magicmap .lplayer'+num+'  {  opacity:0.0; border:thick solid ' + col0[9] + ';} ' +
				' #magicmap .iplayer'+num+'  {  opacity:0.8; border:thick dashed ' + col0[9] + ';} ' +
				' #magicmap .mplayer'+num+'  {  opacity:0.0; border:thick solid ' + col0[9] + ';} ' +
				' #magicmap .jplayer'+num+'  {  opacity:10.8; border:thick dashed  ' + col0[9] + ';} ' +
				' #magicmap .nplayer'+num+'  {  opacity:0.0; border:thick solid ' + col0[9] + ';} ' +
				' .playerBG'+num+' { color: ' + col0[9] + '; font-weight: bold} ' +
				' .playerBGDD'+num+' { background-color: ' + col1[9] + '; } ';
		GM_addStyle(styl);
	}
    }

    if (fog) // create extra player for Unknown territories.
    {
	for (name in playersArray)
	{
		UID++;
	}
	playersArray["Unknown"] = new Player("Unknown",UID,pl_Colors[NID]);
    }

    // ID THE MAP
    mapName = unsafeWindow.mapFile;
    mapSize = unsafeWindow.mapResolution;

//    ---- Map Analysis ----
    cc_log("Map Analysis");
    analyseMap();

    cc_log("Starting Request XML");
    GM_xmlhttpRequest({method: 'GET',url: 'http://www.conquerclub.com/maps/'+mapName+'.xml?nocache='+Math.random(),headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey/0.3 BOB' , 'Accept': 'application/xml,text/xml'},onload: 
	function(responseDetails) 
	{
		customStartWaiting("Parsing XML");

		cc_log("Received XML response");

		var parser = new DOMParser();
		var dom = parser.parseFromString(responseDetails.responseText,"application/xml");

		smallwidth = dom.getElementsByTagName('smallwidth')[0].textContent.normiliseSpaces();
		smallheight = dom.getElementsByTagName('smallheight')[0].textContent.normiliseSpaces();
		largewidth = dom.getElementsByTagName('largewidth')[0].textContent.normiliseSpaces();
		largeheight = dom.getElementsByTagName('largeheight')[0].textContent.normiliseSpaces();


		if (num_players>8) // make the right hand side scrollable for BR's
		{
			var h = smallheight;
			if (mapSize == "L")
				h = largeheight;

			rightside.style.height = h+"px";
			rightside.style.overflow = "auto";
		}


		var entries = dom.getElementsByTagName('name');

		for (var i = 0; i < entries.length; i++) 
		{
			var parent = entries[i].parentNode;
			comp = parent.getElementsByTagName('components');
			if (comp.length==1)
			{
				bonus = parent.getElementsByTagName('bonus');
				if (bonus.length==1)
					parseContinent(parent);
				else
					parseObjective(parent);
			  
			}
			else
				parseTerritory(parent);
		}
		
		// get minimum reinforcements - defaulted to 3.
		var entries = dom.getElementsByTagName('minreinforcement');
		if (entries.length>0) 
		{
			minimumReinforcements = entries[0].textContent.normiliseSpaces();
		}
		
		// read out the reinforcements matrix.
		var entries = dom.getElementsByTagName('reinforcement');

		for (var i = 0; i < entries.length; i++) 
		{
			lower = entries[i].getElementsByTagName('lower')[0].textContent.normiliseSpaces();
			upper = entries[i].getElementsByTagName('upper')[0].textContent.normiliseSpaces();
			divisor = entries[i].getElementsByTagName('divisor')[0].textContent.normiliseSpaces();
			reinforcementsArray.push(new Reinforcement(lower, upper, divisor));
		}
		cc_log("Parsed XML");


//             -- Calculate Defensive Borders -- 

		for (var cou in countriesArray) 
		{
			var cc = countriesArray[cou];
			// Now update all those places I can attack with my details
			for (var k=0; k < cc._borders.length; k++)
			{
				var bb = countriesArray[cc._borders[k]];
				if (!bb._DefendBorders[cc._name]) 
				{
					bb._DefendBorders.push(cc._name);
				}
			}
			for (var k=0; k < cc._bombards.length; k++)
			{
				var bb = countriesArray[cc._bombards[k]];
				bb._bombardedBy.push(cc._name);
			}
		}

		//Auto Scroll to Game
	    	if( OPTIONS['jumptomap'] )
	    	{
			window.setTimeout(jtm,1000);
		}

		// always create this DIV now - we need it for the mapfade number show...
		var magicMapDiv = document.createElement('div');
		magicMapDiv.id="magicmap";
		magicMapDiv.innerHTML = "";
		map.parentNode.appendChild(magicMapDiv);

		APPLY_MAPFADE(OPTIONS,mapName);

		showMapInspectDiv();

		updatePlayerCards();

		processLog(0, true, true);

		checkElimSummary();

		recalcRedemption();

		updateCountries();

		updateContinents();

		updateObjectives();

		if (OPTIONS["textMapType"] != "Off")
		{
			updateTextmap(true);
		}

		createStats(true);

		APPLY_TEXTMAP(myOptions);

		APPLY_STATS(myOptions);

		updateMagicMap(false);

		colourCodeDD();

		updateMenuHiderHeight();

    		if (OPTIONS["floatActions"] == "On")
    		{
			setFormWidth();
		}

		checkForUpdate();

	   if (showDeleteAll)
	   {
		showDeleteSnapshots();
	   }

	stopWaiting();
    cc_log("Done after request");          
    }}); // END Map Get response Function

    cc_log("Done Outside request");



    cc_log("Building the Settings Menu");          
    createGameMenu();
    
    prepareMenuHider();

     cc_log("Checking for previous versions");
    
    var hrs = document.getElementById('hrs'); // Tr0y's & roberts mods
    var bhrs = document.getElementById('bhrs'); // BOB
    if (hrs ) {
        alert("You are currently running more than one Conquer Club Greasemonkey script. This causes unpredictable results/errors. It is recommended that you disable the 'Conquer Club' and/or 'Conquer Club - Roberts Mods' scripts leaving only this script 'Conquer Club - BOB' enabled.\n\n To do this right click on the Greasemonkey icon and untick the redundant scripts, then press F5 to refresh the page." );
    }
    

	/* Ishiro's Confirm Commands code */
	var newsendRequest = unsafeWindow.sendRequest;
	unsafeWindow.sendRequest = function(command) {
    /* ---    Confirmation Popups --- */
      if (((command == 'End Attacks' || command == 'End Fortification' || (command == 'Fortify' && !(dashboard.innerHTML.indexOf("Unlimited") > -1))) && myOptions['confirmEnds']) || (command == 'Auto-Attack' && myOptions['confirmAutoAttack']) || (command == 'Deploy' && myOptions['confirmDeploy']))
      {
        var message = command;
      	if (command == "Fortify") // if the command is fortify - then we are actually doing an "end fort" so modify the message.
      		message = "End Fortification";
         if (confirm("Are you sure you wish to "+message+"?"))
         {
            return newsendRequest(command);
         }
         else {
            return false;
         }
      }
      else {
         return newsendRequest(command);
      }
   }

   updateMenuHiderHeight();

} // End GAME Processing

var downloadedLog = "";
var logLength = 0;

function getFullLog()
{
	var thisLog = logDiv.innerHTML.split('<br>'); //Get logs on screen
	
	if (downloadedLog=="" && !thisLog[0].has("Game has been initialized"))
	{
		var failureMsg = "Log Downloading Failed - Would you like to retry?";
		try
		{
			var url = "http://www.conquerclub.com/game.php?";
			url+= "game=" + unsafeWindow.game.value + "&ajax=1&map_key=" + unsafeWindow.mapKey + "&log_number=" + unsafeWindow.logNumber + "&chat_number=" + unsafeWindow.chatNumber+"&full_log=Y";
			var req = new XMLHttpRequest();
			//Setting the URL with a synchronous GET
			req.open('GET',url,false);
			req.send(null);
		}
		catch (e)
		{
			alert(e);
			reloadFullLog(failureMsg);
			return "";
		}
		if (req.status != 200)
		{
			reloadFullLog(failureMsg);
			return "";
		}

		var response = req.responseText.split("&");
		downloadedLog = unescape(response[14]);
		logLength = thisLog.length-1;
	}
	var amendedLog = downloadedLog.split('<br />');
	
	for (var i=logLength;i<thisLog.length-1;i++)
	{
		amendedLog.push(thisLog[i]);
	}
	return amendedLog;

}

function reloadFullLog(message)
{
	if (confirm(message))
	{
		location.href = location.href + "&full_log=Y";
	}
}

// the following are the major functions for this script.

function processLog(start, init, showProgress, end)
{
    if (showProgress)
    	customStartWaiting("Processing Log");
    var log = getFullLog();
    if (end)
    {
    	start=0;
    	init=true;
    }
    if (!init)
    {
	rounds = stored_rounds;
	num_turnins = stored_num_turnins;
	for (name in playersArray)
	{
		playersArray[name]._skipped = stored_skipped[playersArray[name]._pid];
		playersArray[name]._lastBonus = stored_last_bonus[playersArray[name]._pid];
	}
	if (fog)
	{
		for (name in playersArray)
		{
			playersArray[name]._calculatedCountries = stored_countries[playersArray[name]._pid];
		}
	}
	TerminatorSummary = stored_terminator_summary;
    }
    else
    {
	rounds = stored_rounds = 0;
	num_turnins = stored_num_turnins = 0;
	for (name in playersArray)
	{
		playersArray[name]._skipped = stored_skipped[playersArray[name]._pid] = 0;
		playersArray[name]._lastBonus = stored_last_bonus[playersArray[name]._pid] = 0;
	}
	if (fog)
	{
		for (name in playersArray)
		{
			playersArray[name]._calculatedCountries = stored_countries[playersArray[name]._pid] = 0;
		}
	}
	TerminatorSummary = stored_terminator_summary = "";

	if (fog)
	{
		var np = num_players;
		if (np==2)
			np=3;
		var startingTerrs = Math.floor(totalStartCountries / np);
		for (name in playersArray)
		{
			if (name!="Neutral")
				playersArray[name]._calculatedCountries = startingTerrs;
		}
	}
    }

    /*---- Process Log ----*/
    cc_log("Starting Log Processing");
    cc_log("Log Processing Info - Length :" + log.length);
    for( i = start; i < log.length; i++ )
    {
    	if (end)
    	{
    		var dateStr = log[i].split(" - ")[0];
    		var front = dateStr.split(" ")[0];
    		var back = dateStr.split(" ")[1];
		if (front)
		{
	    		var dArray = front.split("-");
	    		var dyr = dArray[0];
	    		var dmth = dArray[1];
	    		dmth--; //minus 1 off of the month
	    		var dday = dArray[2];
	    		if (back)
	    		{
		    		var tArray = back.split(":");
		    		var thour = tArray[0];
		    		var tmin = tArray[1];
		    		var tsec = tArray[2];
		    		var dateStr2 = Date.UTC(dyr, dmth, dday, thour, tmin, tsec);
		    		if (dateStr2 >= end.getTime())
		    		{
		    			break;
		    		}
		    	}
		}
    	}
        // cc_log("Log Processing Info - indx :" + i + ":" + log[i]);
        // ID the player
        name = log[i].split(/<[^>]*>/)[1];
        if (! playersArray[name] && log[i].has('<span class="player')) {
                // Player Rename mid game?
                var num = parseInt(log[i].split(/"/)[1].split(/player/)[1]);
                name = pIndxs[num-1].innerHTML;
            }
        // Process the log
        if( log[i].has(" gets a card") ){
            playersArray[name]._skipped = 0;
            playersArray[name]._deferred = 0;
        }
        else if(  log[i].has(" ran out of time") ){
            playersArray[name]._skipped = 0;
            playersArray[name]._deferred = 0;
        }
        else if(  log[i].has(" fortified ") )
        {
            playersArray[name]._skipped = 0;
            playersArray[name]._deferred = 0;
        }
        else if (log[i].has(" deployed ")  )
        {
            playersArray[name]._skipped = 0;
        }
        else if(log[i].has(" attacked "))
	{
            playersArray[name]._skipped = 0;
	    if (fog)
	    {
		//add 1 to player who conquered...
		playersArray[name]._calculatedCountries++;
		// then minus 1 from player who lost...
		conquered = log[i].substring(log[i].indexOf("conquered"));
        	lossname = conquered.split(/<[^>]*>/)[1];
		if (!playersArray[lossname] && conquered.has('<span class="player')) 
		{
                	// Player Rename mid game?
                	var num = parseInt(conquered.split(/"/)[1].split(/player/)[1]);
			if (num!=0)
                		lossname = pIndxs[num-1].innerHTML;
            	}
		if (lossname!="neutral player") // don't minus from neutral player...
		{
			playersArray[lossname]._calculatedCountries--;
		}
	    }

	}
        else if(log[i].has(" bombarded "))
	{
            playersArray[name]._skipped = 0;
	    if (fog)
	    {
		// then minus 1 from player who lost...
		annihilated = log[i].substring(log[i].indexOf("annihilated"));
        	lossname = annihilated.split(/<[^>]*>/)[1];
		if (!playersArray[lossname] && annihilated.has('<span class="player')) 
		{
                	// Player Rename mid game?
                	var num = parseInt(annihilated.split(/"/)[1].split(/player/)[1]);
			if (num!=0)
                		lossname = pIndxs[num-1].innerHTML;
            	}
		if (lossname!="neutral player") // don't minus from neutral player...
		{
			playersArray[lossname]._calculatedCountries--;
		}
	    }

	}


        
        else if( log[i].has(" missed a turn") ){
            playersArray[ name ]._skipped += 1;
        }
        else if( log[i].has(" cashed") ){
            playersArray[ name ]._skipped = 0;
            num_turnins++;
        }
        else if( log[i].has(" eliminated ") ){
            playersArray[ name ]._skipped = 0;
            TerminatorSummary += log[i] + " in round - "+rounds+"<br/>"
        }
        else if( log[i].has(" receives ") )
	{
		playersArray[name]._skipped = 0; // Copied from above as receives was previously checked for and did this.
		//calculate how many armies received... add to last bonus.
		if (playersArray[name]._lastBonusFixed)
		{
			playersArray[name]._lastBonus = 0;
			playersArray[name]._lastBonusFixed = false;
		}
		armies = log[i].substring(log[i].indexOf("receives")+8,log[i].indexOf("armies")-1);
		armies = parseInt(armies,10);
		if (log[i].has("deferred"))
			playersArray[name]._deferred = armies;
		else
			playersArray[name]._lastBonus = playersArray[name]._lastBonus + armies;
	}
        else if( log[i].has(" lost ") )
        {
	    if (fog)
	    {
	    	playersArray[name]._calculatedCountries--;
	    }
        }
        else if( log[i].has(" loses ") ){
            playersArray[name]._deferred = 0;
            TerminatorSummary += log[i] + " in round - "+rounds+"<br/>"
        }
        else if( log[i].has(" gains ") ){
            playersArray[ name ]._skipped = 0;
            TerminatorSummary += log[i] + " in round - "+rounds+"<br/>"
        }
        else if( log[i].has(" was kicked out ") || log[i].has(" was a deadbeat") )
        {
            playersArray[ name ]._skipped = -1;
            TerminatorSummary += log[i] + " in round - "+rounds+"<br/>"
	    if (fog && isTeamGame())
	    {
	    	//work out where the armies go to after DB gives territories to team mate.
	    	var goto = calculateBenficiary(name);
	    	if (goto!="-1")
	    	{
	    		playersArray[goto]._calculatedCountries+=playersArray[name]._calculatedCountries;
	    	}
		playersArray[ name ]._calculatedCountries = 0;
	    }
            else if (m_gameType != eGameType.TERMINATOR) 
	    { // if player kicked out and not terminator then blat this to 0.
		playersArray[ name ]._calculatedCountries = 0;
	    }
	}
        else if( log[i].has("Incrementing game to round") || log[i].has("Game has been initialized") )
	{
		stored_rounds = rounds++;
		// update starter place - and stored vars.
		logFixed=i;
		stored_num_turnins = num_turnins;
		stored_skipped = new Array();
		stored_last_bonus = new Array();
		for (name in playersArray)
		{
			stored_skipped.push(playersArray[name]._skipped);
			stored_last_bonus.push(playersArray[name]._lastBonus);
			playersArray[name]._lastBonusFixed = true;
			playersArray[name]._deferred = 0;
		}
		if (fog)
		{
			stored_countries = new Array();
			for (name in playersArray)
			{
				stored_countries.push(playersArray[name]._calculatedCountries);
			}
		}
		stored_terminator_summary = TerminatorSummary;
        }
        else if (log[i].has("won the game"))
        {
		showDeleteAll = true;
		if (!end && !start)
		{
			logFixed=i+1; // Only show this on initial load.
		}
        }
    }
    var termDiv = document.getElementById('summary');
    if (termDiv)
    {
	termDiv.innerHTML = TerminatorSummary;
    }
    else
    {
    	var termWrapper = document.getElementById('termWrapper');
	termDiv = document.createElement('div');
	termDiv.id="summary";
	termWrapper.appendChild(termDiv);
	termDiv.innerHTML = TerminatorSummary;
    }
}

function calculateBenficiary(name)
{
	var curPlayer = playersArray[name];
	var curTeam = teamNumber(curPlayer._pid);
	for (var otherName in playersArray) // loop through from top to bottom...
	{
		possPlayer = playersArray[otherName];
		if (possPlayer._pid != curPlayer._pid) // ensure not the same player...
		{
			if (teamNumber(possPlayer._pid)==curTeam) // ensure on the same team...
			{
				if (possPlayer._skipped!=-1) // ensure teammate not a DB already!
				{
					return otherName;
				}
			}
		}
	}
	return "-1";
}

function createStats(showProgress)
{
    if (showProgress)
    	customStartWaiting("Creating Statistics Table");
    statsStr = "";
    statsStr2 = "";
    tmp = "";
    var tmp2 = "";
    unk = "";
    var unk2 = "";

    var plyrCnt = 0;

statsStr = "<table align=center style='width:100%;border:1px solid #FFF;background:#eee;' rules=rows><tr style='font-weight:normal;' ><td nowrap><b>P</b>layer&nbsp;</td>" + ( m_bonusCards?"<td nowrap><b>C</b>ards&nbsp;</td>":"" )+"<td nowrap><b>M</b>issed<br><b>T</b>urns&nbsp;</td><td nowrap><b>A</b>rmies&nbsp;</td><td nowrap><b>T</b>erritories&nbsp;";
if (fog){statsStr +="[Calc]";}
statsStr+= "</td><td nowrap><b>S</b>trength&nbsp;</td><td nowrap><b>L</b>ast<br><b>B</b>onus&nbsp;</td><td nowrap><b>A</b>rmies due<br>(<b>T</b> + <b>C</b> + <b>TB</b>)&nbsp;</td><td nowrap><b>D</b>eferred<br><b>A</b>rmies&nbsp;</td>" + ( m_bonusCards  ?"<td nowrap><b>C</b>ard Set<br><b>E</b>stimate&nbsp;</td>":"" )+"<td nowrap><b>C</b>ontinents&nbsp;</td></tr>";
statsStr2 = "<table align=center style='width:100%;border:1px solid #FFF;background:#eee;' rules=rows><tr style='font-weight:normal;' ><td nowrap><b>P</b>layer&nbsp;</td>" + ( m_bonusCards?"<td nowrap><b>C</b>ards&nbsp;</td>":"" )+"<td nowrap><b>M</b>issed<br><b>T</b>urns&nbsp;</td><td nowrap><b>A</b>rmies&nbsp;</td><td nowrap><b>T</b>erritories&nbsp;";
if (fog){statsStr2 +="[Calc]";}
statsStr2 += "</td><td nowrap><b>L</b>ast<br><b>B</b>onus&nbsp;</td><td nowrap><b>A</b>rmies<br><b>D</b>ue&nbsp;</td><td nowrap><b>D</b>eferred<br><b>A</b>rmies&nbsp;</td><td nowrap><b>C</b>ontinents&nbsp;</td></tr>";

var LastTeamID = -1;
var teamArmies = 0;
var teamTerritories  = 0;
var teamCalcedTerrs = 0;
var teamStrength =0;
var teamID = 0;

    for( name in playersArray )
    {
        if( playersArray[name]._countries != 0 || playersArray[name]._calculatedCountries != 0)
        {
	    var tid = teamNumber(playersArray[name]._pid);
	    if (tid!=0)
            	teamID = tid;
            if (isTeamGame() && LastTeamID != -1 && LastTeamID != teamID && name!="Unknown") 
            {
                var pctArmies = Math.round(teamArmies*100/totalArmies);
                var pctCountries = Math.round(teamTerritories*100/totalCountries);
		pctCalcCountries = Math.round(teamCalcedTerrs*100/totalCountries);
            
                var curpid = 0;
                var nameStr = "Team " + LastTeamID;
                var isEliminated = false;
                if (LastTeamID != 0 ) {
                statsStr+= "<tr>" + 
                            makeTableCellText(isEliminated, curpid, nameStr) + 
                            ( m_bonusCards?  makeTableCellText(isEliminated, curpid, "") :"" ) +
                            makeTableCellText(isEliminated, curpid, "") + 
                            makeTableCellText(isEliminated, curpid,  teamArmies +" ( " + pctArmies +"% )"); 
			if (fog)
				statsStr += makeTableCellText(isEliminated, curpid, teamTerritories + " ( " + pctCountries +"% ) ["+teamCalcedTerrs+" (" + pctCalcCountries +"%) ]" );
			else
				statsStr += makeTableCellText(isEliminated, curpid, teamTerritories + " ( " + pctCountries +"% )" );
                statsStr += makeTableCellText(isEliminated, curpid, teamStrength) + 
                            makeTableCellText(isEliminated, curpid, "") + 
                            makeTableCellText(isEliminated, curpid, "") + 
                            makeTableCellText(isEliminated, curpid, "") + 
                            "</tr>\n";
                statsStr2+=    
                
                            "<tr>" +
                            makeTableCellText(isEliminated, curpid, nameStr) + 
                            ( m_bonusCards?  makeTableCellText(isEliminated, curpid, "") :"" ) +
                            makeTableCellText(isEliminated, curpid, "") + 
                            makeTableCellText(isEliminated, curpid,  teamArmies );
			if (fog)
                            statsStr2+= makeTableCellText(isEliminated, curpid, teamTerritories+" ["+teamCalcedTerrs+"]" );
			else
                            statsStr2+= makeTableCellText(isEliminated, curpid, teamTerritories); 
                statsStr2+= makeTableCellText(isEliminated, curpid, "") + 
                            makeTableCellText(isEliminated, curpid, "") + 
                            "</tr>\n";
                }
                teamArmies = 0;
                teamTerritories  = 0;
                teamStrength =0;
                teamCalcedTerrs = 0;
            }

            var curpid = playersArray[name]._pid;
            var nameStr = '<span class="ClickPlayerJumper">'+name+'</span>';
            
            var cardStr = m_bonusCards ?  '<img width="18" height="16" title="' + playersArray[name]._cards + 
                                          ' Bonus Cards" alt="' + playersArray[name]._cards + ' Bonus Cards" class="icon3" src="static/cards.gif"/>' + playersArray[name]._cards + ' '
                                       :  '';
                                       
            var pctArmies = (totalArmies!=0)?Math.round(playersArray[name]._armies*100/totalArmies):0;
            var pctCountries = Math.round(playersArray[name]._countries*100/totalCountries);
            var pctCalcCountries = Math.round(playersArray[name]._calculatedCountries*100/totalCountries);
            var numArmiesNextTurn = ( playersArray[name]._pid )?calcArmiesNextTurn(playersArray[name]._countries):0;
	    if (fog)
		numArmiesNextTurn = ( playersArray[name]._pid )?calcArmiesNextTurn(playersArray[name]._calculatedCountries):0;
            var eliminated1 = (playersArray[name]._skipped == -1) ? "<span class=eliminated>" : "" ;
            var eliminated2 = (playersArray[name]._skipped == -1) ? "</span>" : "";
            var isEliminated = (playersArray[name]._skipped == -1);
            // strength = Armies + PotentialArmies - 2*Countries/3
            var pl_Strength = Math.round( ( playersArray[name]._armies + (((numArmiesNextTurn + playersArray[name]._continentBonus + playersArray[name]._territoryBonus)*(playersArray[name]._skipped+1))) + (getTurnInP(playersArray[name]._cards) * RedemptionValue) - (2*playersArray[name]._countries/3) ) * 100 )/100;

            var currentArmies = playersArray[name]._armies;
            var cards = playersArray[name]._cards;
            var countries = playersArray[name]._countries;
	    var calced_countries = playersArray[name]._calculatedCountries;
            var continentBonus = playe