dojo.require("dijit._base.place");
dojo.require("dojo.string");

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
	    ? Math.ceil(from)
	    : Math.floor(from);
    if (from < 0)
	 from += len;

    for (; from < len; from++)
    {
	 if (from in this &&
		this[from] === elt)
	   return from;
    }
    return -1;
  };
}

String.prototype.replaceAll = function(str_to_replace, replacement_str)
{
	var last_replacement_index = 0;
	var subject = this;

	if(subject.indexOf(str_to_replace) == -1)
		return subject;
	

	
	while(subject.indexOf(str_to_replace, last_replacement_index)>=0)
	{
		last_replacement_index = subject.indexOf(str_to_replace, last_replacement_index) + replacement_str.length;
		subject = subject.replace(str_to_replace, replacement_str);
	}

	return subject;
}

String.prototype.trim = function()
{
	var subject = this;
	return subject.replace(/^\s+|\s+$/g, '');
}

/* This utility function resolves the string movieName to a Flash object reference based on browser type. */
function GetMovieObj(movieName) 
{
	if (navigator.appName.indexOf("Microsoft") != -1) 
	{
		return window[movieName];
	}
	else 
	{
		return document[movieName];
	}
}


// ========================================================
// declare the JSFeature namespace
var JSFeature = {};
JSFeature.white_out_box_connect_handle_onscroll = null;
JSFeature.white_out_box_connect_handle_onresize = null;
JSFeature.center_on_screen_connect_handle_onscroll = null;
JSFeature.center_on_screen_connect_handle_onresize = null;
JSFeature.center_on_screen_node_array = new Array();

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
 
JSFeature.Base64 = {
 
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = JSFeature.Base64._utf8_encode(input);
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
 
		}
 
		return output;
	},
 
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}
 
		output = JSFeature.Base64._utf8_decode(output);
 
		return output;
 
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
 
}

JSFeature.CreateCookie = function(name,value,days)
{
	if(days)
	{
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else
		var expires = "";
	
	document.cookie = name+"="+value+expires+"; path=/";
}

JSFeature.ReadCookie = function(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) 
	{
		var c = ca[i];
		while (c.charAt(0)==' ') 
			c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) 
			return c.substring(nameEQ.length,c.length);
	}
	return null;
}

JSFeature.EraseCookie = function(name) 
{
	JSFeature.CreateCookie(name,"",-1);
}


JSFeature.HtmlEntities = function(text)
{
	text = text.replaceAll('"', '&quot;');
	text = text.replaceAll('<', '&lt;');
	
	return text;
}
JSFeature.IsValidEmailAddress = function(address)
{
	var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
	if(reg.test(address) == false) 
	{
		return false;
	}
	return true;
}
JSFeature.AppendNodeToBody = function(node)
{
	var body_tag = dojo.query('body')[0];
	body_tag.appendChild(node);
}
JSFeature.RemoveNodeFromBody = function(node)
{
	var body_tag = dojo.query('body')[0];
	body_tag.removeChild(node);
}
JSFeature.ShowWhiteOut = function(opacity, color, z_index)
{
	JSFeature.HideWhiteOut();
	if(!JSFeature.white_out_box_connect_handle_onscroll)
	{
		JSFeature.white_out_box_connect_handle_onscroll = dojo.connect(window, "onscroll", JSFeature._AdjustWhiteOut);
	}
	if(!JSFeature.white_out_box_connect_handle_onresize)
	{
		JSFeature.white_out_box_connect_handle_onresize = dojo.connect(window, "onresize", JSFeature._AdjustWhiteOut);
	}
	var wo_obj = dojo.byId('feature_white_out');
	if(!wo_obj)
	{
		var wo_obj = document.createElement('div');
		wo_obj.id = 'feature_white_out';
		dojo.style(wo_obj, "opacity", opacity ? opacity : .5);
		dojo.style(wo_obj, "backgroundColor", color ? color : "black");
		wo_obj.style.display = 'block';
		wo_obj.style.position = 'absolute';
		wo_obj.style.zIndex = (z_index ? z_index : "1000");
		wo_obj.innerHTML = '';
		JSFeature.AppendNodeToBody(wo_obj);
	}
	
	JSFeature._AdjustWhiteOut();
}

JSFeature._AdjustWhiteOut = function(css_class_name)
{
	var wo_obj = dojo.byId('feature_white_out');
	if(wo_obj)
	{
		var vp_obj = dijit.getViewport();
		wo_obj.style.width = vp_obj.w + 'px';
		wo_obj.style.height = vp_obj.h + 'px';
		wo_obj.style.left = vp_obj.l + 'px';
		wo_obj.style.top = vp_obj.t + 'px';
	}
}
JSFeature.HideWhiteOut = function(css_class_name)
{
	var wo_obj = dojo.byId('feature_white_out');
	
	if(wo_obj)
	{
		if(JSFeature.white_out_box_connect_handle_onscroll)
		{
			dojo.disconnect(JSFeature.white_out_box_connect_handle_onscroll);
			JSFeature.white_out_box_connect_handle_onscroll = null;
		}

		if(JSFeature.white_out_box_connect_handle_onresize)
		{
			dojo.disconnect(JSFeature.white_out_box_connect_handle_onresize);
			JSFeature.white_out_box_connect_handle_onresize = null;
		}

		JSFeature.RemoveNodeFromBody(wo_obj);
	}
}

JSFeature.CenterOnScreen = function(node)
{
	JSFeature.center_on_screen_node_array.push(node);
	
	if(!JSFeature.center_on_screen_connect_handle_onscroll)
	{
		JSFeature.center_on_screen_connect_handle_onscroll = dojo.connect(window, "onscroll", JSFeature._UpdateCenterOnScreen);
	}
	if(!JSFeature.center_on_screen_connect_handle_onresize)
	{
		JSFeature.center_on_screen_connect_handle_onresize = dojo.connect(window, "onresize", JSFeature._UpdateCenterOnScreen);
	}
	
	JSFeature._UpdateCenterOnScreen();
}

JSFeature.StopCenterOnScreen = function(node)
{
	try
	{
		var tmp_array = JSFeature.center_on_screen_node_array;
		JSFeature.center_on_screen_node_array = new Array();
		var i;
		var cur_node;
		for(i=0; i<tmp_array.length; i++)
		{
			cur_node = tmp_array[i];
			if(cur_node != node)
			{
				JSFeature.center_on_screen_node_array.push(cur_node);
			}
		}
	}
	catch(e)
	{
	}
}

JSFeature._UpdateCenterOnScreen = function()
{
	try
	{
		var i;
		var node, vp_obj, nw, nh, new_w, new_h;
		for(i=0; i<JSFeature.center_on_screen_node_array.length; i++)
		{
			node = JSFeature.center_on_screen_node_array[i];
			vp_obj = dijit.getViewport();
			nw = node.offsetWidth;
			nh = node.offsetHeight;
			
			new_w = (vp_obj.w/2 - nw/2) + vp_obj.l;
			new_h = (vp_obj.h/2 - nh/2) + vp_obj.t;
			
			node.style.left = new_w > 0?new_w + 'px':'0px';
			node.style.top = new_h > 0?new_h + 'px':'0px';
		}
	}
	catch(e)
	{
	}
}

JSFeature.GetNodePosArray = function(obj)
{
	var curleft = curtop = 0;
	if (obj.offsetParent) 
	{
		do
		{
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	
	return [curleft,curtop];
}

// left, top, width, height
JSFeature.GetNodeBoundingBox = function(obj)
{
	var left = 0;
	var top = 0;
	var width = 0;
	var height = 0;
	var right = 0;
	var bottom = 0;
	
	var tmp_pos_array = JSFeature.GetNodePosArray(obj);
	
	left = tmp_pos_array[0];
	top = tmp_pos_array[1];
	width = obj.offsetWidth;
	height = obj.offsetHeight;
	right = left + width;
	bottom = top + height;
	
	return {'left':left,'top':top,'width':width,'height':height,'right':right,'bottom':bottom};
}

// ========================================================
// declare error box registry namespace
var TWErrorRegistry = {obj_reg:[]};
TWErrorRegistry.AddObj = function(obj)
{
	var i;
	for(i=0; i<this.obj_reg.length; i++)
	{
		if(this.obj_reg[i].id == obj.id)
		{
			this.obj_reg[i] = obj;
			return;
		}
	}
	
	this.obj_reg.push(obj);
}
TWErrorRegistry.GetObj = function(id)
{
	var i;
	for(i=0; i<this.obj_reg.length; i++)
	{
		if(this.obj_reg[i].id == id)
			return this.obj_reg[i];
	}
}
// declare the TWError class
function TWError(parent_node, id, css_id)
{
	this.id = id;
	this.css_id = css_id;
	this.title;
	this.message_array = new Array();
	this.custom_create_callback = null;
	this.parent_node = null;
	
	this.SetTitle('The follow errors have occured:');
	this.SetParentNode(parent_node);
	this.Hide();
	TWErrorRegistry.AddObj(this);
	 
}

TWError.prototype.SetParentNode = function(parent_node)
{
	this.parent_node = parent_node;
}

TWError.prototype._pri_DefaultHTML = function()
{
	var i;
	var output = '';
	output += 	'<div id="'+this.id+'_error_box" class="'+(this.css_id?this.css_id+'_':'')+'error_box" style="display:none;">';
	output += 		'<div id="'+this.id+'_error_box_hide_link_wrapper" class="'+(this.css_id?this.css_id+'_':'')+'error_box_hide_wrapper">';
	output += 			'<div id="'+this.id+'_error_box_hide_link" class="'+(this.css_id?this.css_id+'_':'')+'error_box_hide_link" onclick="TWErrorRegistry.GetObj(\''+this.id+'\').Hide();">';
	output += 				'[close]';
	output += 			'</div>';
	output += 		'</div>';
	output += 		'<div id="'+this.id+'_error_box_title_wrapper" class="'+(this.css_id?this.css_id+'_':'')+'error_title_wrapper">'
	output += 			'<div id="'+this.id+'_error_box_title" class="'+(this.css_id?this.css_id+'_':'')+'error_title">'+this.title+'</div>';
	output += 		'</div>'
	output += 		'<div id="'+this.id+'_error_box_message_wrapper" class="'+(this.css_id?this.css_id+'_':'')+'error_box_message_wrapper">'
	for(i=0; i<this.GetErrorMessageCount(); i++)
	{
		output += '<div id="'+this.id+'_error_box_message_'+(i+1)+'" class="'+(this.css_id?this.css_id+'_':'')+'error_box_message">'+this.message_array[i]+'</div>';
	}
	output += 		'</div>';
	output += 	'</div>';
	
	return output;
}

TWError.prototype.SetCustomCreateCallback = function(callback)
{
	this.custom_create_callback = callback;
}


TWError.prototype._pri_CreateHTML = function()
{
	if(this.custom_create_callback)
		return this.custom_create_callback(this);
	else
		return this._pri_DefaultHTML();
}

TWError.prototype.Create = function()
{
	if(this.parent_node)
	{
		this.parent_node.innerHTML = this._pri_CreateHTML();
	}
}
TWError.prototype.Delete = function()
{
	if(this.parent_node)
	{
		this.parent_node.innerHTML = '';
	}
}
TWError.prototype.Show = function()
{
	this.Create();
	
	if(this.parent_node)
		this.parent_node.style.display = '';
	
	if(document.getElementById(''+this.id+'_error_box'))
	{
		document.getElementById(''+this.id+'_error_box').style.display = '';
	}
}

TWError.prototype.Hide = function()
{
	this.Create();
	
	if(this.parent_node)
		this.parent_node.style.display = 'none';
	
	if(document.getElementById(''+this.id+'_error_box'))
	{
		document.getElementById(''+this.id+'_error_box').style.display = 'none';
	}
}

TWError.prototype.SetTitle = function(title)
{
	this.title = title;
	this.Create();

}

TWError.prototype.SetMessageArray = function(message_array)
{
	this.message_array = message_array;
	this.Create();
}
TWError.prototype.AddMessage = function(message)
{
	this.message_array.push(message);
	this.Create();
}
TWError.prototype.ClearMessageArray = function(message)
{
	this.message_array = new Array();
	this.Create();
}
TWError.prototype.GetErrorMessageCount = function()
{
	return this.message_array.length;
}