var ruler = null;

jQuery.extend({
	calcWnd: [],
	tout : null,
	saving : false,
	try_cnt : 0,
	mode : null,
	sequence : [],
	q : null,
	passage_id : null,
	scored : false,
	img_c : [],
	questions : [],
	passages : {},
	review : [],
	preloaded : [],
	answers : [],
	cellIndex : function( obj ) {
		if ($.browser.safari) {
			var ci = ( obj.cellIndex == 0 ? -1 : obj.cellIndex );
	
			for ( var x = 0; ci == -1 && x < obj.parentElement.cells.length; x++ ) {
				if ( obj === obj.parentElement.cells[x] ) {
	      			ci = x;
	    		}
	  		}
	  		return ci;
  		}
  		
  		return obj.cellIndex;
	},
	log : function(str) {
		var date = new Date(),
			date_str = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds() + '.' + date.getMilliseconds();
		
		//console.log(date_str, ' : ', str);
		//$('#consoleContent').append(date_str, ' : ', str, '<br>');	
	},
	my_resize : function() {
		var height = Math.max($('div.question').height(), $.iUtil.getClient().h - 200); 
		$('#workspace_container, #passage, #passage_container').height(height + 'px');
		
		$('#passage_container, #passage, #question, #question_container').width($.iUtil.getClient().w / 2);
	},
	preloadQuestionImages : function(q_no) {
		if ($($.preloaded).index(q_no) == -1) { // preload images from next question
			var image = new Image();
			$('img' ,$.questions[q_no]).each(function (i) {
				image.src = this.src;
				});	
			$.preloaded[$.preloaded.length] = q_no;
		}
	},
	showQuestion : function(q_no) {
		$.log('showQuestion(' + q_no + ':' + $.sequence[q_no] + ')'); 
		
		if (!$.questions[q_no]) {
			alert('question is not preloaded');
			return;
		}

		$('#toolbar_container, #footer_container').css('display', $.browser.msie ? 'block' : 'table-row');
		
		var scroll = 0;
		if ($('#passage_container').css('display') != 'none') {
			scroll = document.getElementById('passage').scrollTop;
		}

	
		$('#question_container').html($.questions[q_no]);
		
		var p_id = parseInt($('div.question/#passageid').val()),
			calc = parseInt($('div.question/#calc').val()),
			formula = parseInt($('div.question/#formula').val()),
			ruler = parseInt($('div.question/#ruler').val());

		
		
		if (p_id) { 
			if (p_id != $.passage_id) {
				$('#passage_container').css('display', $.browser.msie ? 'block' : 'table-cell');
				$('#passage_container').html($.passages[p_id]);
	                        $('#passage').width(parseInt($.iUtil.getClient().w / 2) + 'px' );
				$.passage_id = p_id;
			} 
			
			if ('none' == $('#passage_container').css('display')) {
				$('#passage_container').css('display', $.browser.msie ? 'block' : 'table-cell');
			}
		} else {
			$('#passage_container').hide();
		}
		
		
					
		if (calc) $('#d_calc').show();
		else $('#d_calc').hide();
		
		if (formula) $('#d_formula').show();
		else $('#d_formula').hide();
		
		if (ruler) $('#d_ruler').show();
		else $('#d_ruler').hide();
		
		
		var qtype = $('#qtype').val();
		$.log('showQuestion() : ' + qtype); 
		switch (qtype) {
			case 'multichoice': $.q = $.multichoice; break;
			case 'shadein': $.q = $.shadein; break;
			case 'bubblegrid': $.q = $.bubblegrid; break;
			case 'cgrid': $.q = $.cgrid; break;
			case 'bargraph' : $.q = $.bargraph; break;
			case 'shortanswer':
			case 'openended' : $.q = $.openended; break;
			case 'piechart' : $.q = $.piechart; break;
			case 'dragexplain' :
			case 'dragexplain' :
			case 'dragdrop':
			case 'dragdropfibtable':
			case 'dragexplainfibtable':
			case 'spatialdragexplain': $.q = $.ddhtml; break;
			default:
				$.q = $.html;
		}
		
		$.q.init();
		InitDragging();
		$("img[@name='draggit']").css('cursor', $.browser.msie ? 'hand' : 'pointer' );

		if ($.answers[q_no]) {
			//alert($.answers);
			$.q.setValue($.answers[q_no]);
		}

		
		if (qtype != 'multichoice') {
			$('#checkanswer_container').css('display', $.browser.msie ? 'block' : 'table-row');
			$('#d_checkanswer').show();
		} else{
			$('#checkanswer_container').hide();
			$('#d_checkanswer').show();
		}
		

		if ($.scored || $.mode > 1) {
			$.getFeedback();
		}
		$.my_resize();
		
		$.nopaste.enable();
	},
	piechart : {
		init : function() {
			$.log('piechart.init()');
			var pies = $('#pies').val();
			
			$('div.question').append(makePieChart(pies));
		},
		getValue : function() {
			return pie_t.GetValue();
		},
		setValue : function(value) {
			return pie_t.SetValue(value);
		}
	},
	openended : {
		init : function() {
			$.log('openended.init()');
			
			if ($('#explain').length == 0) {
				$("div.question").append($.TEXTAREA({'id': 'explain'}).css('width', '100%').css('height', '200px'));
			}
		},
		getValue : function() {
			$.log('openended.getValue()');
			
			var value = $("#explain").val();
			$.log('openended.getValue(): ' + value );
			
			return value;
		},
		setValue : function(value) {
			$.log('openended.setValue(' + value + ')');
			$("#explain").val(value);
		} 
	},
	multichoice : {
		init : function() {
			var self = this;
			$.log('multichoice.init()');
			this._preloadImages();
			$('div.question td.mc_btn').hover(
				function() { 
					var el = $('img', this),
						src = (this.className.indexOf('mc_chk_btn') > -1) ? '/image/test/a_btn.h.hover.gif' : '/image/test/a_btn.hover.gif';
					
					el.attr('def_src', el.attr('src')).attr('src', src);
				}, 
				function() { 
					var el = $('img', this);
					el.attr('src', el.attr('def_src')); 
				}
			);
			
			$('div.question td.mc_btn').click(function () { 
					$('div.question td.mc_chk_btn').attr('class', 'mc_btn');
					$('div.question td.mc_btn img').attr('src', '/image/test/a_btn.gif');
					
					$(this).attr('class', 'mc_chk_btn mc_hover');
					
					$('img', this).attr('src', '/image/test/a_btn.h.gif')
						.attr('def_src', '/image/test/a_btn.h.gif')
					
					//if ($.scored || $.mode > 1)
						$.getFeedback();
			});
		},
		getValue : function() {
			$.log('multichoice.getValue()');
			
			var value = parseInt($('div.question td.mc_chk_btn').attr('id'));
			$.log('multichoice.getValue() : ' + value);
			
			return value;
		},
		setValue : function(value) {
			$.log('multichoice.setValue(' + value + ')');
			
			$('div.question td.mc_chk_btn').attr('class', 'mc_btn');
			$('div.question td.mc_btn:eq(' + parseInt(value - 1) + ') img').attr('src', '/image/test/a_btn.h.gif');
			$('div.question td.mc_btn:eq(' + parseInt(value - 1) + ')').attr('class', 'mc_chk_btn');
			
			
		},
		_preloadImages : function() {
			var imgs = ['/image/test/a_btn.gif', '/image/test/a_btn.h.gif', '/image/test/a_btn.hover.gif', '/image/test/a_btn.h.hover.gif'];
			for (var i = 0; i > imgs.length; i++) {
				var img = new Image();
				img.src = imgs[i];
			}
		}
	},
	shadein : {
		init : function() {
			$.log('shadein.init()');
			
			var table = $.TABLE({'border' : '1', 'cellPadding' : 0, 'cellSpacing' : 0, 'id': 'shadein_table'});
			
			for (var i = 0; i < $('#rows').val(); i++) { //FIXME : not optimal
				var tr = $.TR({});
				for (var j = 0; j < $('#cols').val(); j++)
					tr.append($.TD({width: $('#width').val(), height:$('#height').val(), 'class' : 'si_cell_norm '}, $.IMG({'src' : '/image/spacer.gif'})));
				table.append(tr);
			}
			
			$('#shadein').append(table);
			$('#shadein_table td').bind('mousedown', function() { $.shadein.down = true; $.shadein.sel(this); });
			$(document).bind('mouseup', function() { $.shadein.down = false; });
			
			
			$('#shadein_table td').hover(function() { $(this).addClass('si_cell_sel'); }, function() { $(this).removeClass('si_cell_sel'); clearTimeout($.shadein.to); })
				.bind('mouseover', function() { $.shadein.sel(this); });
		},
		sel : function(obj){
			if ($.shadein.down) {
				$('#shadein_table td').removeClass('si_cell_now');
				$(obj).toggleClass('si_cell_chk').removeClass('si_cell_sel').addClass('si_cell_now');
				$.shadein.to = setTimeout("$('#shadein_table td.si_cell_now').addClass('si_cell_sel').removeClass('si_cell_now');", 500);
			}
					
		},
		getValue : function() {
			$.log('shadein.getValue()');
			
			var value = $('#shadein_table td.si_cell_chk').length;
			$.log('shadein.getValue() :' + value);
			
			return value;
		},
		setValue : function(value) {
			$.log('shadein.setValue(' + value + ')');
			
			$('#shadein_table td').attr('class', 'si_cell_norm').lt(value).addClass('si_cell_chk');
		}
	},
	bubblegrid : {
		values : [],
		init : function() {
			$.log('bubblegrid.init()');
			
			this._preloadImages();
			this.values = [];
			var m = parseInt($('#m').val()), n = parseInt($('#n').val()), 
				prefix = $('#prefix').val(), suffix = $('#suffix').val(),
				table = $.TABLE({'cellPadding' : 0, 'cellSpacing' : 0, 'id': 'bubblegrid_table'}),
				i, j;
			
			var tr = $.TR({});
			for (j = 0; j < m+n+1; j++) {
				this.values[j] = (j == m ? '.' : 0);
				tr.append($.TH({'class' : j == m ? 'bgrid_cell dot' : 'bgrid_cell header'}, j == m ? '.' : '\u00A0'));
			}
			table.append(tr);
			
			var tbody = $.TBODY({'rules' : 'cols'}),
				item = $('<div/>').attr('class', 'bg_item')
					.append('<img class="norm" src="/image/script/bubblegrid/blank.gif" width="25" height="24"/>')
					.append('<img class="chk" src="/image/script/bubblegrid/blank.chk.gif" width="25" height="24"/>')
					.append('<img class="hover" src="/image/script/bubblegrid/blank.hover.gif" width="25" height="24"/>');
					
			
			for (i = 0; i <= 9; i++) {
				tr = $.TR({});
				for (j = 0; j < m+n+1; j++) {					
					tr.append(
						$.TD(
							{'class' : j == m ? 'bgrid_cell dot' : 'bgrid_cell norm'},
							j == m ? '.' : item.clone().prepend($('<span class="bg_text"/>').html(i || '0'))
						)
					);
				}
				table.append(tr);
			}
			
			$('#bubblegrid').append(
				$.TABLE({}, 
					$.TR({'vAlign':'top'}, 
						$.TD({}, $.SPAN({}, prefix)), 
						$.TD({}, table), 
						$.TD({}, $.SPAN({}, suffix)))));
						
			$('#bubblegrid_table td.bgrid_cell').hover(
				function() { 
					$(this).addClass('hover'); }, 
				function() { 
					$(this).removeClass('hover'); clearTimeout($.bubblegrid.to); }
			);
			
			$('#bubblegrid_table td.bgrid_cell').click(function() {
				$('#bubblegrid_table td').removeClass('bgrid_cell_now');
				
				$(this).addClass('now').removeClass('hover');
				
				$.bubblegrid._changeValue($.cellIndex(this), this.parentNode.rowIndex - 1);
				
				$.bubblegrid.to = setTimeout("$('td.now').addClass('hover').removeClass('now');", 500);
			});
			
		},
		_preloadImages : function() {
			var imgs = ['/image/script/bubblegrid/blank.gif', '/image/script/bubblegrid/blank.chk.gif', '/image/script/bubblegrid/blank.hover.gif'];
			var img = new Image;
			for (var i = 0; i > imgs.length; i++) {
				img.src = imgs[i];
			}
		},
		_changeValue: function(col, value) {
			if (value == -1)
				return;

			var table = $('#bubblegrid_table').get(0), i;

			for (i = 0; i < table.rows.length; i++)  {
				$(table.rows[i].cells[col]).removeClass('chk');
			}
			
			value = value || '0';
			if ($(table.rows[0].cells[col]).text() == value) {
				$(table.rows[0].cells[col]).html('&nbsp;');
				this.values[col] = 0;
			} else {
				this.values[col] = value;
				
				//alert(parseInt(value) + 1);
				$(table.rows[0].cells[col]).html(value || '0');
				$(table.rows[parseInt(value)+1].cells[col]).addClass('chk');
			}
			
		},
		setValue: function(value) {
			$.log('bubblegrid.setValue(' + value + ')');
			
			var m = parseInt($('#m').val()), n = parseInt($('#n').val()),
				m_str = Math.floor(value).toString(),
				n_str = Math.round((value - Math.floor(value))*Math.pow(10, n)).toString(),
				i, j;
				
				for (i = m_str.length - 1; i >= 0; i--) 
					this._changeValue(m - m_str.length + i, m_str.charAt(i));
		
				if (0 == n_str) return;
					
				for (i = n_str.length - 1; i >= 0; i--)
					this._changeValue(m + n + 1 - n_str.length + i, n_str.charAt(i));

		},
		getValue: function() {
			$.log('bubblegrid.getValue()');
			
			var value = parseFloat(this.values.join(''));
			$.log('bubblegrid.getValue() :' + value);
			
			return value;
		}
	},
	cgrid : {
		value : [],
		xmin : 0, xmax : [], ymin : 0, ymax : 0, 
		tminor : 0, tmajor : 0,
		width : 0, height : 0,
		maptype : null,
		kx : null, ky : null, 
		rx : null, ry : null,
		jg : null,
		init : function() {
			$.log('cgrid.init()');
			
			this.xmin = parseFloat($('#cgrid/#xmin').val()), this.xmax = parseFloat($('#cgrid/#xmax').val()),
				this.ymin = parseFloat($('#cgrid/#ymin').val()), this.ymax = parseFloat($('#cgrid/#ymax').val()),
				this.tminor = parseFloat($('#cgrid/#tminor').val()), this.tmajor = parseFloat($('#cgrid/#tmajor').val()),
				this.width = parseFloat($('#cgrid/#width').val()), this.height = parseFloat($('#cgrid/#height').val()),
				this.maptype = $('#cgrid/#maptype').val();
			
			this.kx = this.width/(this.xmax - this.xmin);
			this.ky = this.height/(this.ymax - this.ymin);
			
			this.step = (this.maptype == 'minor' ? this.minor : this.major) || this.tmajor;

			$('#cgrid').width(this.width).height(this.height);
			
			var pos = $.iUtil.getPosition($('#cgrid').get(0));
			this.rx = pos.x; 
			this.ry = pos.y;
			
			this.cy = this.ymax == 0 ? this.ymax : 
				this.ymin == 0 ? this.ymin : this.ymin + (this.ymax - this.ymin)/2;
			this.cx = this.xmax == 0 ? this.xmax : 
				this.xmin == 0 ? this.xmin : this.xmin + (this.xmax - this.xmin)/2;			
			
			this.jg = new jsGraphics('cgrid');
			
			this.drawXAxis();
			this.drawYAxis();
			
			this.line(this.xmin, this.cy, this.xmax, this.cy, '#000000');
			this.line(this.cx, this.ymin, this.cx, this.ymax, '#000000');
			
			this.jg.drawImage('/image/spacer.gif', this.rx, this.ry, this.width, this.height);
			
			this.jg.paint();
			
			$('#cgrid').mousemove(function(e) {
				var p = $.iUtil.getPointer(e),
					step = $.cgrid.tminor||$.cgrid.tmajor,
					w = $('#smarker').width(),
					h = $('#smarker').height(),
					x = step*Math.round($.cgrid._x(p.x)/step),
					y = step*Math.round($.cgrid._y(p.y)/step);
					
				if (x < $.cgrid.xmin || x > $.cgrid.xmax ||
					y < $.cgrid.ymin || y > $.cgrid.ymax) {
					// mouseout doesnt throw if cursor is over marker 
					
					return;	
				}
					
				
								
				$('#smarker').css('left', $.cgrid.x_(x) - w/2 + 'px').
					css('top', $.cgrid.y_(y) - h/2 + 'px');
			});
			
			$('#cgrid').click(function(e) {
				var p = $.iUtil.getPointer(e),
					step = $.cgrid.tminor||$.cgrid.tmajor,
					w = $('#marker').width(),
					h = $('#marker').height();
					
				$.cgrid.value[0] = parseFloat((step*Math.round($.cgrid._x(p.x)/step)).toPrecision(5));
				$.cgrid.value[1] = parseFloat((step*Math.round($.cgrid._y(p.y)/step)).toPrecision(5));
				
				$('#marker').css('left', $.cgrid.x_($.cgrid.value[0]) - w/2 + 'px').
					css('top', $.cgrid.y_($.cgrid.value[1]) - h/2 + 'px');
			});
			
			$('#cgrid').mouseout(function() { $('#smarker').css('top', '-100px'); });

			$('#cgrid').append(
				$.IMG({'id' : 'marker', 'src' : '/image/script/cgrid/marker.png'}),
				$.IMG({'id' : 'smarker', 'src' : '/image/script/cgrid/smarker.png'})
			);
			
		},
		x_ : function(x) { 
			if (!isFinite(this.kx)) {
				return value = this.rx + this.width/2;	;
			}

			return this.rx + (x - this.xmin)*this.kx;;
		},
		_x : function(px) { 
			return this.xmin + (px - this.rx)/this.kx;;
		},
		y_ : function(y) {
			if (!isFinite(this.ky)) {
				return this.ry + this.height/2;
			}
			
			return this.ry + this.height - (y - this.ymin)*this.ky;;
		},
		_y : function(py) {
			return this.ymin + (this.ry - (py - this.height))/this.ky; ;
		},
		line : function(x1, y1, x2, y2, color, stroke) {
			this.jg.setColor(color||'silver');
			this.jg.setStroke(stroke||1);
			this.jg.drawLine(this.x_(x1), this.y_(y1), this.x_(x2), this.y_(y2));
		},
		drawXAxis : function() {
			if (this.xmax == this.xmin)
				return;
		
			var step = (this.maptype == 'minor' ? this.minor : this.major)||this.tmajor;
			for (i = this.xmin; i <= this.xmax; i += step) {
				this.line(i, this.ymin, i, this.ymax, 'silver');
			}
			
			this.jg.setColor('#000000');
			this.jg.setStroke(2);
			for (i = this.xmin; i <= this.xmax; i += this.tmajor) {
				this.jg.drawLine(this.x_(i), this.y_(this.cy)+3, this.x_(i), this.y_(this.cy)-3);
				valstr = String(parseFloat(i.toPrecision(6)));
				len = valstr.length;
				this.jg.drawString(parseFloat(i.toPrecision(6)), this.x_(i)-4*len, this.y_(this.cy)+4);
			}
			this.jg.setStroke(1);
			
			if (this.tminor) {
				for (i = this.xmin; i <= this.xmax; i += this.tminor ) {
					this.jg.drawLine(this.x_(i), this.y_(this.cy)+1, this.x_(i), this.y_(this.cy)-1);
				}
			}			
		},
		drawYAxis : function() {
			if (this.ymax == this.ymin)
				return; 
			
			var step = (this.maptype == 'minor' ? this.minor : this.major)||this.tmajor;
			for (i = this.ymin; i <= this.ymax/step; i += step) {
				this.line(this.xmin, i, this.xmax, i, 'silver');
			}

			this.jg.setColor('#000000');
			this.jg.setStroke(2);
			for (i = this.ymin; i <= this.ymax; i += this.tmajor) {
				this.jg.drawLine(this.x_(this.cx)+3, this.y_(i), this.x_(this.cx)-3, this.y_(i));
				this.jg.drawString(parseFloat(i.toPrecision(6)), this.x_(this.cx)+4, this.y_(i)-6);
			}
			this.jg.setStroke(1);
			
			if (this.tminor) {			
				for (i = this.ymin; i <= this.ymax; i += this.tminor) {
					this.jg.drawLine(this.x_(this.cx)+1, this.y_(i), this.x_(this.cx)-1, this.y_(i));
				}
			}
		},
		getValue : function() {
			$.log('cgrid.getValue()');

			//var value = this.value;
			$.log('cgrid.getValue() :' + this.value);
		
			return this.value.slice(0);
		},
		setValue : function(value) {
			$.log('cgrid.setValue(' + value + ')');
			
			if (value == '')
				return;
			var w = $('#marker').width(),
			    h = $('#marker').height();
					
			this.value = value.slice(0);
			
			$('#marker').css('left', $.cgrid.x_($.cgrid.value[0]) - w/2 + 'px').
				css('top', $.cgrid.y_($.cgrid.value[1]) - h/2 + 'px');
		}	
	},
	bargraph : {
		spacePressed : false,
		binded : false,
		colors : ['red', 'orange', 'yellow', 'green', 'blue', 'darkblue', 'purple'],
		timer : [],
		params : {}, 
		value : [],
		init : function() {
			$.log('bargraph.init()');
			
			var params = {}, args = ['width', 'height', 'leftmargin', 'rightmargin', 'topmargin', 'bottommargin', 'cols', 'ymax', 'ymin', 'step'], i;
			for (i = 0; i < args.length; i++) {
				params[args[i]] = parseInt($('#bargraph/#' + args[i]).val());
			}
			params['img'] = $('#bargraph/#img').val();	
			params['ky'] = (params['height'] - params['topmargin'] - params['bottommargin'])/(params['ymax'] - params['ymin']);

			this.params = params;

			if (!this.binded) {
				$(document).bind('keydown', function(event) { 
					if (32 == event.keyCode) {
						$.bargraph.spacePressed = true; 
						$.log('bgraph - mega step');
					}
				});
				$(document).bind('keyup', function(event) { 
					if (32 == event.keyCode) {
						$.bargraph.spacePressed = false; 
						$.log('bgraph - normal step');
					}
				} );
			}


			$('#bargraph').css('background', 'no-repeat url("' + params['img'] + '")')
				.width(params['width']).height(params['height'])
				.css('paddingTop', params['topmargin'])
				.css('paddingLeft', params['leftmargin'])
				.css('paddingRight', params['rightmargin'])
				.css('paddingBottom', params['bottommargin']);
 
			var tr = $.TR({'vAlign' : 'bottom', 'align' : 'center'}), tr_ctrl = $.TR({}).attr('align', 'center');
			for (i = 0; i < params['cols']; i++) {
				tr.append($.TD({}, $.DIV({}, '').css('backgroundColor', this.colors[i]).width('50%').height('0px').css('fontSize', '1px')));
				tr_ctrl.append($.TD({'nowrap' : 'nowrap'}, 
					$.IMG({'src': '/image/script/bargraph/plus.png', 'class' : 'bgraph_ctrl inc'}).bind('contextmenu', function() { return false; }),
					$.IMG({'src': '/image/script/bargraph/minus.png', 'class' : 'bgraph_ctrl dec'}).bind('contextmenu', function() { return false; })
					)
				);
				this.value[i] = params['ymax'] > 0 ? params['ymin'] : params['ymax'];
			}
				
			$('#bargraph').append(
				$.TABLE({'id' : 'positive',
					'cellPadding' : '0', 'cellSpacing' : '0', 
					'width' : params['width'] - params['leftmargin'] - params['rightmargin'] + 'px',
					'height' : params['height'] - params['topmargin'] - params['bottommargin'] + 'px'}, 
					tr
				)
			);
			
			$('#bargraph').wrap("<div id='bargraph_container'>");
			$('#bargraph_container').append(
				$.TABLE({'id' : 'ctrl_table', 'border' : '0', 'cellPadding': '0', 'cellSpacing': '0'}, tr_ctrl)
				.width(params['width'] - params['leftmargin'] - params['rightmargin'])
				.css('marginLeft', params['leftmargin'])
				.css('marginRight', params['rightmargin'])
			);			
			
			$('#ctrl_table tr td img')
				.mousedown(function() {
					clearInterval(this.timer);
					this.timer = setInterval(
						'$.bargraph._changeValue(' + $.cellIndex(this.parentNode) + ', ' + ($(this).attr('class').indexOf('inc') == -1 ? false : true) + ');', 
						200);
					}
				)
				.mouseup(function() { clearInterval(this.timer); } )
				.mouseout(function() { clearInterval(this.timer); } )
				.click( function() { $.bargraph._changeValue($.cellIndex(this.parentNode),  ($(this).attr('class').indexOf('inc') == -1 ? false : true) ); } );
		},
		_changeValue : function(col, increment, value) {
			var params = this.params;
			var step = this.spacePressed ? params.step * 5 : params.step;

			if (!value) {
 				value = this.value[col];
				value += (true == increment) ? step : -step;
 			}
			
			if (value < params.ymin) {
				value = params.ymin;
			}

			if (value > params.ymax) {
                                value = params.ymax;
                        }

					
			$('#bargraph td div').eq(col).height(value*params.ky + 'px');
			this.value[col] = value;
		},
		getValue : function() { 
			$.log('bargraph.getValue()');
			$.log('bargraph.getValue() :' + this.value);
			
			return this.value.slice(0); 
		},
		setValue : function(value) {
			$.log("bargraph.setValue(" + value + ")");
		
			for (var i = 0; i < value.length; i++) {
				this._changeValue(i, null, value[i]);
			}
		}
	},
	ddhtml : {
		init : function() {
			$.log("ddhtml.init()");
			
			
			$("div.question/div.qfoil/*").each(
				function() {
					if ($(this).css('position') == 'absolute') {
						$(this).css('top', $.iUtil.getPosition(this).y + 130 + 'px');
					}
				}
			);
			
			
			makeDHTML();
		},
		getValue : function() { 
			$.log("ddhtml.getValue()");
			
			var result = $.html.getValue(); 
			if (null == result)
				result = {};
				
			result.drag = ddhtml.getValue()
			
			if ($.ddhtml.isEmpty(result))
				result = null;
				
			$.log("ddhtml.getValue() :" + $.toJSON(result));
			return result;
		},
		setValue : function(value) { 
			$.log("ddhtml.setValue(" + $.toJSON(value) + ")");
					
			if (value.drag)
				ddhtml.setValue(value.drag);
			$.html.setValue(value); 
		},
		isEmpty : function(value) {
			var dd_ok = true, f_ok = true, e_ok = true;
			
			if (value.fib) {
				if (value.fib.length == 0) f_ok = false;
			} else {
				f_ok = false;
			}
			
			if (!value.explain) e_ok = false;
			 
				
			if (value.drag) {
				var size = 0;
				for (var i in value.drag) {
					size++;
				}
				
				if (0 == size)
					dd_ok = false;
			} else {
				dd_ok = false
			}
			
			return !(dd_ok || f_ok || e_ok);
		}
	},
	html : {
		init : function() {
			$.log('html.init()');
		},
		getValue : function() {
			$.log('html.getValue()');
			var result = {};
			
			var obj = $('div.question div.qfoil input');
			if (obj.length > 0) {
				var value = [];
				
				for (var i = 0; i < obj.length; i++) {
					value[parseInt(obj.eq(i).attr('id').replace(/fib/i, '') - 1)] = ("" == obj.eq(i).val() ? null : obj.eq(i).val()); 
				}
				result.fib = value;
			}
			
			obj = $('#explain');
			if (obj.length == 1) 
				result.explain = obj.val();
			
						
			$.log('html.getValue() :' + $.toJSON(result));
			return $.html.isEmpty(result) ? null : result;			
		},
		setValue : function(value) {
			$.log('html.setValue(' + $.toJSON(value) + ')');
			
			if (!value)
				return;
			
			if (value.explain)
				$('#explain').html(value.explain);
			
			
			if (value.fib) {
				for (var i = 0; i < value.fib.length; i++) {
					$('#fib' + parseInt(i+1)).val(value.fib[i]);
				}
			}
			
		},
		isEmpty : function(value) {
			var f_ok = true, e_ok = true;
			
			if (value.fib) {
				if (value.fib.length == 0) f_ok = false;
			} else {
				f_ok = false;
			}
			
			if (!value.explain) e_ok = false;
			 
			
			return !(f_ok || e_ok);			
		}
	},
	endoftest : function() {
		$.log('endoftest()');
		
		if (($.mode == 0 || $.mode == 1)  && $.scored) {
			$.score.go();
			return;
		}
		
		$('#toolbar_container, #passage_container, #checkanswer_container, #footer_container').css('display', 'none');
		$('#question_container').html($.BR({})).append(
			$.TABLE({'cellPadding' : 10, 'cellSpacing' : 5, 'width' : '700px', 'align' : 'center', 'vAlign' : 'center', 'border' : 1, 'class' : 'endoftest'}, 
				$.TR({},
					$.TD({'colSpan': 2, 'class' : 'caption', 'align' : 'center'}, 'END OF TEST')
				),
				$.TR({},
					$.TD({'width' : '350px'}, 
						$.DIV({}, $.IMG({'src' : '/image/test/stopsign.gif', 'alt' : 'STOP'})).css('text-align', 'center'),
						$.BR({}),
						$.P({}, "You are about to complete this test"),
						$.P({}, "Click on the SCORE TEST button to end the test. Once it is scored, you cannot change any answers. Otherwise, if you marked any question for review"),
						$.OL({},
							$.LI({}, "Click on the question number to return to that question"),
							$.LI({}, "Double-check your answer"),
							$.LI({}, "Click on Double-check Later box to remove the checkmark"),
							$.LI({}, "Click Go To End to return here")
						)
					),
					$.TD({'width' : '350px'},
						$.DIV({}, $.A({}, $.IMG({'src': '/image/test/review.gif', 'alt' : 'review'})).bind('click', function() { $.showQuestion(0); } )).css('text-align', 'center'), $.BR({}),
						$.DIV({'id' : 'score_container'}, $.A({}, $.IMG({'src': '/image/test/score.gif', 'alt' : 'score'})).bind('click', $.score.go)).css('text-align', 'center'), $.BR({}),
						$.HR({}),
						$.DIV({}, 
							$.P({}, 'Questions not answered'),
							$.P({'id' : 'not_answered'}, '')	
						),
						$.HR({}),
						$.DIV({}, 
							$.P({}, 'Questions marked for review'),
							$.P({'id' : 'marker_review'}, '')	
						)
					)
				)
			)
		);
		
		if ($.scored) {
			$('#score_container').hide();
		}
		
		$('td#question_container a img').hover(
                	function () {
                        	var arr = this.src.match(/(.*)(.hover)?.(gif|jpg|jpeg|png)/);
                        	if (arr[2] == '.hover')
                                	return;

                        	this.src = arr[1] + '.hover.' + arr[3];
                	},
                	function () {
                        	var arr = this.src.match(/(.*).hover.(gif|jpg|jpeg|png)/);
                        	this.src = arr[1] + '.' + arr[2];
                	}
        	);		

		var review = [], not_answered = [], i;
		for (i = 0; i < $.review.length; i++) {
			var q_no = $($.sequence).index($.review[i]);
			$('#marker_review').append($.A({'href' : '#', 'id' : q_no, 'class' : 'eot_link'}, q_no + 1).bind('click', function() { $.showQuestion(parseInt(this.id)); } ));
			if (i != $.review.length - 1)
				$('#marker_review').append(",&nbsp;");
		}
		
		var start = true;
		for (i = 0; i < $.sequence.length; i++) {
			if (!$.answers[i]) {
				if (!start) 
					$('#not_answered').append(document.createTextNode(', '));
				
				$('#not_answered').append($.A({'href' : '#', 'id' : i, 'class' : 'eot_link'}, i + 1).bind('click', function() { $.showQuestion(parseInt(this.id)); } ));
				start = false;
			}
		}
	},
	getFeedback : function() {
		var value = $.q.getValue();


		$('#feedback_container').html(
			$.TABLE({'width' : '100%'},
				$.TR({},
					$.TD({}, $.IMG({'src' : '/image/test/left_paren.gif'})),
					$.TD({}, $.IMG({'src' : '/image/loading_bullet.gif'})),
					$.TD({'width' : '100%', 'style': 'font-size:14px;'}, "<p>Loading ...</p>" ),
					$.TD({}, $.IMG({'src' : '/image/test/right_paren.gif'}))
				)
			)		
		);
				
		var d = new Date(),
			options = {
			'q_id' : parseInt($('div.question').attr('id')), 
			'answer' : $.toJSON(value),
			'date': $.date
		};

	
		$.log('request feedback.php :' + $.toJSON(options)); 
		$.ajax({
			type : 'POST',
			url : '/qotd/index/feedback',
			dataType: 'json',
			data : options,
			complete : function(xhr, status) {
				$.log('response feedback.php :' + xhr.responseText);
			},
			success: function(data) {
				if (null == data[0]) data[0] = "No answer selected";
				$('#feedback_container').html(
					$.TABLE({'width' : '100%'},
						$.TR({},
							$.TD({}, $.IMG({'src' : '/image/test/left_paren.gif'})),
							$.TD({}, $.IMG({'src' : '/image/test/mark_' + data[1] + '_' + data[2] + '.gif'})),
							$.TD({'width' : '100%', 'style': 'font-size:14px;'}, "<p>" + data[0] + "</p>" ).css('overflow', 'scroll'),
							$.TD({}, $.IMG({'src' : '/image/test/right_paren.gif'}))
						)
					)
				);
				
				$.fillStatistics(data[3]);
				
				if (!$.opened)
					$('#stat').show();
				
				$.opened = true;
				$('#show_stat').show();
			}
		});
	},
	fillStatistics : function(stat) {
		var	tbl = $('#stat div.data table'),
			letters = [null, 'A', 'B', 'C', 'D', 'E'];
		
		$('tr', tbl).remove();
		$.each(stat[0], function(i, o) {
			var v = Math.round(o[1] / stat[1] * 100);
			tbl.append(
				$.TR({},
					$.TD({}, 0 != stat[2] ? letters[o[0]] : o[0] + ' pts'),
					$.TD({width: '180px'}, '<div style="background-color: blue; width: ' + v + '%">&nbsp;</div>'),
					$.TD({}, v + '%')
				)
			);
		});		 
		
				
		$('#stat .summary').html($.P({}, 'Number of Student Responses: ' + stat[1]));		
	}
});


function init() {
	$("a.m_navy, select.m_navy").bind('click', function() {
		if ($.saving) {
			alert('Data is being saved. Please wait.');
			return;
		}

		var id = $(this).attr('id'), q_prev = parseInt($('#q_no').text()) - 1, go;

		if (isNaN($('div.question').attr('id')) || $.mode >= 1 || ($.mode == 0 && $.scored)) {
			if ('d_course' == id) {
				window.location.href = '/student/';
				return;
			}
			
			if ('d_logout' == id) {
				window.location.href = './?logout';
				return;
			}
			
			if ('d_help' == id) {
				return;
			}
		}
		
		if ('d_jumpto' == id)	{ // ignore first click on select box
			if (0 == this.selectedIndex || 
				parseInt($('#q_no').text()) == this.selectedIndex)
				return;
				
			go = this.selectedIndex - 1;
			this.selectedIndex = 0;
			$(window).focus();
		} else if ('d_prev' == id || 'd_next' == id || 'd_goon' == id) {
			go = parseInt($('#q_no').text()) + (id == 'd_prev' ? -2 : 0);
		} else {
			go = id;
		}
		
		//$('#feedback_container').html('<p>' + !cmp($.answers[q_prev], $.q.getValue()) + '</p>');
//		var save = !cmp($.answers[q_prev], $.q.getValue());
		
		$.answers[q_prev] = $.q.getValue();
		
		var index = $($.review).index(parseInt($('div.question').attr('id'))); 		
		if ($('#review').attr('checked')) {
			if (-1 == index) {
				$.review.push(parseInt($('div.question').attr('id')));	
			}
		} else {
			if (-1 != index) 
				$.review.splice(index, 1);
		}
		
		if (($.mode == 0 || $.mode == 1) && !$.scored) {
			var options = {
				'test_data_id' : $.test_data_id,
				'q_id' : parseInt($('div.question').attr('id')), 
				'answer' : $.toJSON($.q.getValue()), 
				'review': document.getElementById('review').checked ? 1 : 0, 
				'go' : go };
		
			$.log('request go.php :' + $.toJSON(options));
			
			$('#msg').html('Saving answer ...').show(); 
			$.saving = true;
			$.try_cnt = 0;
			
			var a_opts = {
				type : 'POST',
				url : 'go.php',
				data : options,
				dataType: 'json',
				complete : function(xhr, status) {				
					$.log('response go.php : ' + xhr.responseText);
				},
				error : function(xhr, status) {
					clearTimeout($.tout);
					
					if (200 == xhr.status && xhr.responseText) 
					{
						$('#msg').hide();
						$.saving = false;
						alert('Error occured while saving answer.');
						/*
						$('#toolbar_container, #passage_container, #checkanswer_container, #footer_container').css('display', 'none');
						
						$('#question_container').html('<pre>' + xhr.responseText + '</pre>')
							.append('<p>' + $.toJSON({
								testid: $.testid,
								answers: $.answers,
								q: $.q
							}) + '</p>'); 
						*/
						return;
					} 
					
					$.try_cnt++;
														
					if ($.try_cnt < 5) 
					{
						$('#msg').html('Saving answer ... ' + $.try_cnt);
						 var req = $.ajax(this);
						 
						 $.tout = setTimeout(function(){
							if ( req ) { 
								req.abort();
								
								alert('Action timedout. Try again.');
								$('#msg').hide();
								$.saving = false;
							}
						}, 10000);
					}
					else 
					{
						$('#msg').hide();
						$.saving = false;
						alert('Server is not responding. Please try again in few minutes');
					}
				},
				success: function(data) {
					$.log('response go.php : ' + $.toJSON(data));
					clearTimeout($.tout);
					
					if (data.go == 'd_course') {
						window.location = '/student/';
						return;
					}
					
					if (data.go == 'd_logout') {
						window.location = './?logout';
						return;
					}
					
					$('#msg').hide();
					$.saving = false;
					
					if ('d_gotoend' == id) $.endoftest();
					else if ('d_checkanswer' == id) $.getFeedback();
					else $.showQuestion(go);
				}
			};
			
			
			var req = $.ajax(a_opts);
			
			$.tout = setTimeout(function(){
				$('#msg').html('Saving answer ... 0');
				req = $.ajax(a_opts);
				
				$.tout = setTimeout(function(){
					if ( req ) { 
						req.abort();
						var req = $.ajax(this);	
						alert('Action timedout. Try again.');
						$('#msg').hide();
						$.saving = false;
				} }, 5000);
			}, 5000);
			
			
		} else {
			if ($(this).attr('class').indexOf('global') != -1) 
				return;
		
			if ('d_gotoend' == id) $.endoftest();
			else if ('d_checkanswer' == id) $.getFeedback();
			else $.showQuestion(go);
		}			
	});	
	
	$('a img').hover(
		function () { 
			var arr = this.src.match(/(.*)(.hover)?.(gif|jpg|jpeg|png)/);
			if (arr[2] == '.hover')
				return;
			
			if (!$(this).attr('p_src')) $(this).attr('p_src', this.src);	
				
			this.src = arr[1] + '.hover.' + arr[3];
		},
		function () { 
			var arr = this.src.match(/(.*).hover.(gif|jpg|jpeg|png)/);
			//this.src = arr[1] + '.' + arr[2];
			this.src = $(this).attr('p_src');
		}
	);

	$('#d_calc').bind('click', function() {
		$.calcWnd.push(window.open("/scripts/svgcalc/svgcalc.html", "Calc", "menubar=0,resizable=0,width=230,height=480"));
	});

	$('#d_formula').bind('click', function() {
                $.formulaWnd = window.open("/dreamsite/formulachart.htm", "Formula", "menubar=0,resizable=0,width=743,height=423");
        });

	$("#d_cmruler, #d_inchruler").click(function() {
		var name = this.id.substr(2) + ($.grade > 5 ? '1' : '2') + '.png';
		
		if (ruler != null) {
			$('#myRuler, #myCanvas, #myRulerdIi15v').remove();
				
			_x = null;
			_y = null;
			_status = R_MOVE;
			
			
			var val = $.q.getValue();
			ddhtml.resetAll();
			for (var i = 0; i < dd.elements.length; i++) {
				$('#' + dd.elements[i].id ).remove();
			}
			
			
			if (dd.elements) {
				dd.elements = null;
			}
						
			makeDHTML();
			$.q.setValue(val);			
			
		}

		

		
		$('div.question').append(
			$.IMG({'src' : '/image/ruler/' + name, 'id' : 'myRuler', 'name' : 'myRuler'}).width('auto')
				.css('position', 'absolute')
				.css('top', '200px')
				.css('left', '200px'),
			$.DIV({'id' : 'myCanvas', 'name' : 'myCanvas'})
			
		);
		

		setTimeout('ruler = new myRuler();', 500);
		$('#d_jumpto').focus();		
		
				
	});

	$('#d_ruler').bind('click', function(event) {
		var pos = $.iUtil.getPosition(this),
			size = $.iUtil.getSize(this);

		$('#ruler_menu').css('top', parseInt(pos.y + size.h) + 'px')
			.css('left', parseInt(pos.x) + 'px')
			.show();
			
		event.stopPropagation();
		
		$(document).bind('click', function() {
			$('#ruler_menu').hide();
			$(document).unbind('click');
		});
	});
	
	$('#ruler_menu/*').hover(function() { $(this).css('background-color', '#eeeeee');  },
		function() { $(this).css('background-color', '#dddddd');  }
	);

}

$(window).resize($.my_resize);

var digitsonly = "0123456789";
var numbersonly = "-0123456789.\/ ";
var alphanumericonly = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789. ";
var asciicharonly = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!$%*()+=-[]{};:?\\\/<>~\'\" ";
var yesnoonly = "yesnoYESNO";
var morelessonly = "morelsMORELS";
var dollarsonly = "0123456789.$";
var equationonly = "0123456789.+-x*/()^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
// copyright 1999 Idocs, Inc. http://www.idocs.com
// Distribute this script freely but keep this notice in place
function limitinput(myfield, charlist, e)
{
var key;
var keychar;

if (window.event)
   key = window.event.keyCode;
else if (e)
   key = e.which;
else
   return true;
keychar = String.fromCharCode(key);

// control keys
if ((key==null) || (key==0) || (key==8) ||
    (key==9) || (key==13) || (key==27) )
   return true;

// numbers
//else if ((("0123456789.").indexOf(keychar) > -1))
else if (((charlist).indexOf(keychar) > -1))
   return true;

else
   return false;
}
function helpwindow() {
	helpWnd = window.open("/student/help/showme.html", "Help", "menubar=0,resizable=1");
}

function cmp(l, r) {
	if (typeof l == typeof r) {
		switch (typeof l) {
			case 'boolean':
			case 'number':
			case 'string': 
				return  l == r;
			case 'object':
				if (l instanceof Array) {
					if (l.length != r.length)
						return false;
					
					for (var i = 0; i < l.length; i++) {
						if (!cmp(l[i],r[i])) {
							return false;
						}
					}
					
					return true;
				} else {
					for (var i in l) {
						if (!r[i]) return false;
						if (!cmp(l[i], r[i])) return false;	 
						
					}
				
				return true;
			}
		}
	}
	
	return false;
}