TaxTool.TaxTree = function()
{
	var avgTaxHeaderText = 'Avg. Taxpayer';
	var myTaxHeaderText = 'You Spent';
	var percTaxHeaderText = 'Percentage';

	var tree;
	var dataLoader;
	var TotalBudget = 0;
	var AverageTaxpayer = 0;

	var showMyValuesBtn;
	var showAgvValuesBtn;
	var changeVotesBtn;
	var seeResultsBtn;
	var voteBtn;
	var showPercents = false;

	var bot_showMyValuesBtn;
	var bot_showAgvValuesBtn;
	var bot_changeVotesBtn;
	var bot_seeResultsBtn;
	var bot_voteBtn;

	var avgTaxpayerHash = {};
	var multiplierHash = {};
	var alreadyExpanded = {};
	var sorted = {};

	return {
		showResults: false,
		showMyValues: false,

		mediacre: 0,
		social: 0,
		federalAndPropery: 0,

		gridLoaded: false,

        myUsMoney: function(v,z)
        {
            v = (Math.round((v-0)*100))/100;
			if (!z) v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);

            v = String(v);

            var ps = v.split('.');
            var whole = ps[0];
            var sub = ps[1] ? '.'+ ps[1] : (z ? '' : '.00');
            var r = /(\d+)(\d{3})/;

            while (r.test(whole)) {
                whole = whole.replace(r, '$1' + ',' + '$2');
            }

            v = whole + sub;

            if (v.charAt(0) == '-'){
                return '-$' + v.substr(1);
            }

            return "$" +  v;
        },

		percFormat: function(val)
		{
			return (String(Math.round(val)) + '%');
		},
		
		percFormat2: function(val)
		{
			return String(val.toFixed(2) + '%');
		},

		updateOneNode: function(node)
		{
			var res = multiplierHash['z'+node.id];
			//alert(node.attributes.category_name + ' [' + node.attributes.type + ']');

			if (res == 0)
			{
				node.ui.itSetText('average_taxpayer', 'n/a*');
				node.ui.itChbDisable();
				node.ui.itSetText('too_little', '');
				node.ui.itSetText('just_right', '');
				node.ui.itSetText('too_much', '');
			}
			else
			{
				var avgValue = 0;
				var totalBudget = 0;
				
				if (this.showMyValues)
				{
					switch (node.attributes.type)
					{
						case 'T':
							res *= this.mediacre + this.social + this.federalAndPropery;
							break;

						case 'M':
							res *= this.mediacre;
							break;

						case 'S':
							res *= this.social;
							break;

						default:
							res *= this.federalAndPropery;
							break;
					}
										
					if ((node.attributes.type == 'S' || node.attributes.type == 'M') && node.parentNode.id == 0 && this.showPercents)
					{
						avgValue = 'n/a**';
					}
					else
					{
						var tmp = this.mediacre + this.social + this.federalAndPropery == 0 ? 0 : res * 100 / (this.mediacre + this.social + this.federalAndPropery);
						avgValue = this.showPercents ? this.percFormat2(node.attributes.multiplier * 100) : this.myUsMoney(Math.round(res), true);
					}
				}
				else
				{
					if ((node.attributes.type == 'S' || node.attributes.type == 'M') && node.parentNode.id == 0 && this.showPercents)
					{
						avgValue = 'n/a**';
					}
					else
					{
						avgValue = this.showPercents ? this.percFormat2(node.attributes.multiplier * 100) : this.myUsMoney(Math.round(avgTaxpayerHash['z'+node.id]), true);
					}
				}
				
				totalBudget = this.myUsMoney(node.attributes.total_budget, true);
				
				node.ui.itSetText('total_budget', totalBudget);
				node.ui.itSetText('average_taxpayer', avgValue);

				if (this.showResults) {
					node.ui.itChbDisable();
				} else {
					node.ui.itChbEnable();
				}
			}
		},

		doUpdateAllNodes: function(nodes)
		{
			for (var i = 0; i < nodes.length; i++)
			{
				var node = nodes[i];
				this.updateOneNode(node);
				this.doUpdateAllNodes(node.childNodes);
			}
		},

		updateAllNodes: function()
		{
			var node = tree.getRootNode();
			this.doUpdateAllNodes(node.childNodes);
		},

		nodeUIRendered: function(node)
		{
			node.ui.itSetText('too_little', this.percFormat(node.attributes.too_little));
			node.ui.itSetText('just_right', this.percFormat(node.attributes.just_right));
			node.ui.itSetText('too_much', this.percFormat(node.attributes.too_much));
			node.ui.itSetText('total_budget', this.myUsMoney(node.attributes.total_budget, true));
			this.updateOneNode(node);
		},

		nodeExpanded: function(node)
		{
			if (typeof(alreadyExpanded['z'+node.id]) != 'undefined') { return; }

			node.expandChildNodes(true);
			alreadyExpanded['z'+node.id] = true;
		},

		initNode: function(node)
		{
			avgTaxpayerHash['z' + node.id] = node.attributes.average_taxpayer;
			multiplierHash['z' + node.id] = node.attributes.multiplier;

			node.on('uirendered', function(node){ TaxTool.TaxTree.nodeUIRendered(node); });
			node.on('expand', function(node){ TaxTool.TaxTree.nodeExpanded(node); });
		},

		updateVotedNodes: function(nodes, updatedNodes)
		{
			for (var i = 0; i < nodes.length; i++)
			{
				var node = nodes[i];
				
				if (typeof(updatedNodes['z' + node.id]) != 'undefined')
				{
					var arr = updatedNodes['z' + node.id];
					node.ui.itSetText('too_little', this.percFormat(arr[0]));
					node.ui.itSetText('just_right', this.percFormat(arr[1]));
					node.ui.itSetText('too_much', this.percFormat(arr[2]));
				}

				this.updateVotedNodes(node.childNodes, updatedNodes);
			}
		},

		getVoteResult: function(nodes)
		{
			var res = '';

			for (var i = 0; i < nodes.length; i++)
			{
				var node = nodes[i];
				var dataIndex = node.ui.itGetCheckedDataIndex();

				res += (res=='' ? '' : ';') + node.id;

				if (dataIndex !== null)
				{
					switch (dataIndex)
					{
						case 'too_little':
							res += ',l';
							break;

						case 'just_right':
							res += ',r';
							break;

						case 'too_much':
							res += ',m';
							break;
					}
				}

				var tmp = this.getVoteResult(node.childNodes);
				res += (res==''||tmp=='' ? '' : ';') + tmp;
			}

			return res;
		},

		doSeeResults: function()
		{
			changeVotesBtn.show();
			seeResultsBtn.hide();
			voteBtn.hide();

			bot_changeVotesBtn.show();
			bot_seeResultsBtn.hide();
			bot_voteBtn.hide();

			this.showResults = true;
			this.updateAllNodes();
		},

		voteClicked: function()
		{
			var node = tree.getRootNode();
			var res = this.getVoteResult(node.childNodes);

			var shadowform;
			var shadowwin;

			shadowform = new Ext.FormPanel({
				width: 300,
				height: 110,
				frame: true,
				bodyStyle: 'padding:15px 10px 15px 10px; text-align: center;',

				items: [{
					html: 'Submitting votes...'	
				}]
			});

			shadowwin = new Ext.Window({
				layout: 'fit',
				width: 320,
				height: 80,
				resizable: false,
				title: 'Processing request',
				closable: false,
				items: [shadowform],
				shadow: true,
				modal: true,
				border: false
			});

			shadowwin.show();
			
			Ext.Ajax.request({
				url : 'vote.php' ,
				params : { vote : res },
				method: 'POST',

				success: function (result, request)
				{
					if (result.responseText.indexOf('succ:') == 0)
					{
						var updatedNodes = {};
						var arr = result.responseText.substring(5).split(';');

						for (var i = 0; i < arr.length; i++)
						{
							var spl = arr[i].split(',');
							updatedNodes['z'+spl[0]] = [spl[1], spl[2], spl[3]];
						}

						TaxTool.TaxTree.updateVotedNodes(node.childNodes, updatedNodes);
						TaxTool.TaxTree.doSeeResults();

						Ext.MessageBox.alert('Success', '<b>Your votes were successfully submitted.</b><br /><br />Your votes are highlighted in green. Each field contains<br />the aggregate values of all votes collected over time.');
					}
					else Ext.MessageBox.alert('Failed', result.responseText);
					shadowwin.hide();
				},

				failure: function (result, request) {
					Ext.MessageBox.alert('Failed', result.responseText);
					shadowwin.hide();
				}
			});
		},

		calcAverage: function()
		{
			this.doShowMyValues();
		},

		doChangeVotes: function()
		{
			changeVotesBtn.hide();
			seeResultsBtn.show();
			voteBtn.show();

			bot_changeVotesBtn.hide();
			bot_seeResultsBtn.show();
			bot_voteBtn.show();

			this.showResults = false;
			this.updateAllNodes();
		},

		doShowMyValues: function()
		{
			this.showMyValues = true;
			this.showPercents = false;

			showMyValuesBtn.disable();
			showAgvValuesBtn.enable();
			showPercentageValuesBtn.enable();

			bot_showMyValuesBtn.disable();
			bot_showAgvValuesBtn.enable();
			bot_showPercentageValuesBtn.enable();

			tree.itSetHeaderText('average_taxpayer', myTaxHeaderText);
			this.updateAllNodes();
		},

		doShowAvgValues: function()
		{
			this.showMyValues = false;
			this.showPercents = false;

			showMyValuesBtn.enable();
			showPercentageValuesBtn.enable();
			showAgvValuesBtn.disable();

			bot_showMyValuesBtn.enable();
			bot_showPercentageValuesBtn.enable();
			bot_showAgvValuesBtn.disable();

			tree.itSetHeaderText('average_taxpayer', avgTaxHeaderText);
			this.updateAllNodes();
		},
		
		doShowInPercents: function()
		{
			this.showPercents = true;

			showMyValuesBtn.enable();
			showAgvValuesBtn.enable();
			showPercentageValuesBtn.disable();

			bot_showMyValuesBtn.enable();
			bot_showAgvValuesBtn.enable();
			bot_showPercentageValuesBtn.disable();

			tree.itSetHeaderText('average_taxpayer', percTaxHeaderText);
			this.updateAllNodes();
		},
		
		checkIP: function()
		{
			Ext.Ajax.request({
				url : 'isusip.php' ,
				method: 'GET',

				success: function (result, request)
				{
					if (!isNaN(result.responseText))
					{
						if (result.responseText != 0)
						{
							voteBtn.on('mouseover', function() {var el = document.getElementById(this.id); if (el) {el.className = el.className.replace('submit-vote-button', 'submit-vote-button-over').replace('x-btn-over', ''); } });
							voteBtn.on('mouseout', function() {var el = document.getElementById(this.id); if (el) {el.className = el.className.replace('submit-vote-button-over', 'submit-vote-button'); } });
							
							bot_voteBtn.on('mouseover', function() {var el = document.getElementById(this.id); if (el) {el.className = el.className.replace('submit-vote-button', 'submit-vote-button-over').replace('x-btn-over', ''); } });
							bot_voteBtn.on('mouseout', function() {var el = document.getElementById(this.id); if (el) {el.className = el.className.replace('submit-vote-button-over', 'submit-vote-button'); } });
							
							voteBtn.enable();
							bot_voteBtn.enable();
						}
						else
						{
							TaxTool.TaxTree.doSeeResults();
							changeVotesBtn.hide();
							bot_changeVotesBtn.hide();
						}
					}
					else Ext.MessageBox.alert('Failed', result.responseText);
				},

				failure: function (result, request) 
				{
					Ext.MessageBox.alert('Failed', result.responseText);
					shadowwin.hide();
				}
			});
		},
		
		makeSort: function(index, buttons)
		{
			var el = buttons[index];
			
			for (i = 0; i < buttons.length; i++)
			{
				var tmp = buttons[i];
				tmp.container.dom.className = tmp.container.dom.className.replace('x-sorted-header', 'x-not-sorted');
				//tmp.indexer.dom.className = tmp.indexer.dom.className.replace('sorted-asc', 'x-not-sorted').replace('sorted-desc', 'x-not-sorted');
				tmp.indexer.dom.className = tmp.indexer.dom.className.replace('sorted-asc', 'not-sorted').replace('sorted-desc', 'not-sorted');
			}
			
			el.container.dom.className = el.container.dom.className.replace('x-not-sorted', 'x-sorted-header');
			
			var field = el.data;
			sorted[field] = (sorted[field] == null || sorted[field].toLowerCase() == 'desc') ? 'asc' : 'desc';
			
			var sorter = new Ext.tree.TreeSorter(tree, {
				folderSort: true,
				dir: sorted[field],
				sortType: function(node) 
				{
        			return node.attributes[field];
    			}
			});
			
			el.indexer.dom.className = 'sorting-pointer sorted-' + sorted[field];
			
			sorter.doSort(tree.getRootNode());
		},
		
		init: function()
		{
			showMyValuesBtn = new Ext.Toolbar.Button({
				text: 'My money',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doShowMyValues(); }
			});

			showAgvValuesBtn = new Ext.Toolbar.Button({
				text: "Avg. taxpayer's money",
				iconCls: 'blist',
				disabled: true,
				handler: function() { TaxTool.TaxTree.doShowAvgValues(); }
			});

			showPercentageValuesBtn = new Ext.Toolbar.Button({
				text: 'As percentage (%)',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doShowInPercents(); }
			});

			changeVotesBtn = new Ext.Toolbar.Button({
				text: 'Change votes',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doChangeVotes(); }
			});

			seeResultsBtn = new Ext.Toolbar.Button({
				text: 'Show aggregate votes',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doSeeResults(); }
			});

			voteBtn = new Ext.Toolbar.Button({
				text: '',
				minWidth: 92,
				cls: 'submit-vote-button',
				disabled: true,
				handler: function() { TaxTool.TaxTree.voteClicked(); }
			});

			bot_showMyValuesBtn = new Ext.Toolbar.Button({
				text: 'My money',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doShowMyValues(); }
			});

			bot_showAgvValuesBtn = new Ext.Toolbar.Button({
				text: "Avg. taxpayer's money",
				iconCls: 'blist',
				disabled: true,
				handler: function() { TaxTool.TaxTree.doShowAvgValues(); }
			});

			bot_showPercentageValuesBtn = new Ext.Toolbar.Button({
				text: 'As percentage (%)',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doShowInPercents(); }
			});

			bot_changeVotesBtn = new Ext.Toolbar.Button({
				text: 'Change votes',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doChangeVotes(); }
			});

			bot_seeResultsBtn = new Ext.Toolbar.Button({
				text: 'Show aggregate votes',
				iconCls: 'blist',
				handler: function() { TaxTool.TaxTree.doSeeResults(); }
			});

			bot_voteBtn = new Ext.Toolbar.Button({
				text: '',
				minWidth: 92,
				cls: 'submit-vote-button',
				disabled: true,
				handler: function() { TaxTool.TaxTree.voteClicked(); }
			});
			
			dataLoader = new Ext.tree.TreeLoader({
				dataUrl: 'treedata.php',
				uiProviders: {
					'col': Ext.tree.ColumnNodeUI
				}
			})

			dataLoader.on('load', function(loader, node, response)
			{
				for (i = 0; i < node.childNodes.length; i++)
				{
					var n = node.childNodes[i];

					if (n.attributes.category_name == 'Total')
					{
						TotalBudget = n.attributes.total_budget;
						AverageTaxpayer = n.attributes.average_taxpayer;
					}
				}

				TaxTool.TaxTree.gridLoaded = true;
			});

			tree = new Ext.tree.ColumnTree({
				el: 'tree_container',
				width: (420+115+90+40+45+40 + 100) + 2,
				autoHeight: false,
				height: 600,
				rootVisible: false,
				autoScroll: true,
				animate: false,
				title: 'Here is where the money goes',

				tbar: [
					showMyValuesBtn,
					showAgvValuesBtn,
					showPercentageValuesBtn,
					{
						xtype: 'tbfill'
					},
					changeVotesBtn,
					seeResultsBtn,
					voteBtn
				],

					bbar: [
					bot_showMyValuesBtn,
					bot_showAgvValuesBtn,
					bot_showPercentageValuesBtn,
					{
						xtype: 'tbfill'
					},
					bot_changeVotesBtn,
					bot_seeResultsBtn,
					bot_voteBtn
				],

				columns:[{
					header: 'Function And Program',
					width: 315-18 + 100,		// 450 the best
					dataIndex: 'category_name',
					isOneRow: true
				},{
					header: 'Total Budget',
					width: 115,
					itAlign: 'right',
					dataIndex: 'total_budget',
					isOneRow: true
				},{
					header: avgTaxHeaderText,
					width: 100,
					itAlign: 'right',
					dataIndex: 'average_taxpayer',
					isOneRow: true
				},{
					header: 'Too<br />Little',
					width: 50,
					dataIndex: 'too_little',
					itAlign: 'center',
					itCheckboxed: true
				},{
					header: 'About<br />Right',
					width: 55,
					dataIndex: 'just_right',
					itAlign: 'center',
					itCheckboxed: true
				},{
					header: 'Too<br />Much',
					width: 55,
					dataIndex: 'too_much',
					itAlign: 'center',
					itCheckboxed: true
				},{
					header: 'Comments',
					width: 60,
					itComment: true,
					isOneRow: true
				}],

				loader: dataLoader,
				
				root: new Ext.tree.AsyncTreeNode({
					id: '0',
					text: 'Function And Program'
				})
			});

			tree.on('append', function(tree, parent, node, index){ TaxTool.TaxTree.initNode(node); });
			tree.on('insert', function(tree, parent, node, refNode){ TaxTool.TaxTree.initNode(node); });
			tree.render();

			changeVotesBtn.hide();
			bot_changeVotesBtn.hide();

			var vline = document.createElement('DIV');
			vline.style.position = 'absolute';
			vline.style.top = '52px';
			vline.style.left = (325+115+90 - 18) + 'px';
			vline.style.width = '0px';
			vline.style.height = (600-79) + 'px';
			vline.style.borderRight = '1px solid #d0d0d0';
			Ext.get('tree_container').appendChild(vline);
			
			this.checkIP();
		}
	};
}();

