// UTF-8: ï»¿

var Common = {}


// * User ********************************************************************************
// ***************************************************************************************

Common.User =  {
	Init: function() {
		Event.observe($('userpassword'), 'keypress', Common.User.onKeypress);
	},
	Login: function () {
		$('buttonlogin').disable();
		var params = $H({f: 'Login'});
		params = params.merge($('login_form').serialize(true));

		new Ajax.Request('/ajax/ajax_member/', {
				method: 'post',
				parameters: params,
				onSuccess: function(transport) {
					var xmltree = Common.Ajax.ResponseXML(transport.responseXML, true);
					if (xmltree == null) {
						$('username').value = '';
						$('userpassword').value = '';
						$('buttonlogin').enable();
					} else {
						document.location= '/profile/feed/';
					}
				} 
			}
		);		
	
		return false;
	},
	onKeypress: function(event) {
		event = event || window.event;
		if (event.keyCode == Event.KEY_RETURN) {
			Event.stop(event);
			Common.User.Login();
		}
	}
};

// * Ajax ********************************************************************************
// ***************************************************************************************

Common.Ajax = {
	ResponseXML: function(responseXML, show_alert) {
		show_alert = show_alert || false;
	
		var otree = new Common.ObjTree();
		var xmltree = otree.responseXML( responseXML );
		if (xmltree != null && xmltree.response != null && xmltree.response.error != null) {
			if (show_alert && xmltree.response.error.message != null) {
				var title = (xmltree.response.error.title != null ? xmltree.response.error.title : '');
				Common.Alertbox.Show(title, xmltree.response.error.message);
			}
			return null;
		}
		return xmltree;
	}
};


// * Alertbox ****************************************************************************
// ***************************************************************************************

Common.Alertbox = {
	Show: function(title, html) {
		Modalbox.show('<div>' + html + '</div>', {title: title, width: 300, overlayDuration: .15, slideDownDuration: .15, slideUpDuration: .15, resizeDuration: .15});
		return false;
	}
};

// * FormValidator ***********************************************************************
// ***************************************************************************************

Common.FormValidator = {
	ClearErrorColumn: function(error_column) {
		$(error_column).title = '';
		$(error_column).removeClassName('input_accepted');
		$(error_column).removeClassName('input_error');
	},
	IsDate: function(element) {
		element = $(element);
		element.value = element.value.strip();
		var datetest = /^(\d{4})-(\d{2})-(\d{2})(?:\s+(\d{2}):(\d{2}))?$/i;
		var datematch = datetest.exec(element.value);
		if (datematch != null) {
			return true;
		}
		return false;		
	},
	Email: function(element) {
		element = $(element);
		// Strip and ending whitespacing
		element.value = element.value.strip();
		
		var emailtest = /^\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b$/i;
		
		var validated = emailtest.test(element.value)
		return validated;
	},
	Password: function(element) {
		element = $(element);
		
		var validated = true;
		if (element.value.length < 8) {
			validated = false;
		}
		return validated;
	},
	SetErrorColumn: function(columncheck, error_column, title) {
		if (columncheck) {
			$(error_column).title = title;
			$(error_column).removeClassName('input_error');
			$(error_column).addClassName('input_accepted');
		} else {
			$(error_column).title = title;
			$(error_column).removeClassName('input_accepted');
			$(error_column).addClassName('input_error');
		}
	},
	Username: function(element) {
		element = $(element);
		// Strip and ending whitespacing
		element.value = element.value.strip();
		
		var charactertest = /^[a-zåäö0-9 ._\-]+$/i;
		var numbertest = /^[0-9]+$/i;
		
		var validated = true;
		if (element.value.length < 4 || element.value.lenth > 25 || !charactertest.test(element.value)) {
			validated = false;
		} else if (numbertest.test(element.value)) {
			validated = false;
		}
		return validated;
	}	
};

// * Image *******************************************************************************
// ***************************************************************************************

Common.Image = {
	title: '',
	image_path: '',
	imagewidth: 0,
	imageheight: 0,
	showorginal: false,
	onMouseOver: function(image, noclass, reverse) {
		noclass = noclass || false;
		reverse = reverse || false;
		image = $(image);
		image.setStyle({
			cursor: 'pointer'}); 		
		
		if (!noclass) {
			if (reverse) {
				image.removeClassName('imagehover'); 
				image.addClassName('imagenonhover'); 
			} else {
				image.removeClassName('imagenonhover'); 
				image.addClassName('imagehover'); 
			}
		}
	},
	onMouseOut: function(image, reverse) {
		reverse = reverse || false;
		image = $(image);
		if (reverse) {
			image.removeClassName('imagenonhover'); 
			image.addClassName('imagehover'); 
		} else {
			image.removeClassName('imagehover'); 
			image.addClassName('imagenonhover'); 
		}
	},
	onImageResize: function(event) {
		Common.Image.Show(Common.Image.title, Common.Image.image_path, Common.Image.imagewidth, Common.Image.imageheight, !Common.Image.showorginal);
		
		return false;
	},
	Show: function(title, image_path, width, height, showorginal) {
		if (showorginal === undefined) {
			showorginal = false;
		}
		Common.Image.title = title;
		Common.Image.image_path = image_path;
		Common.Image.imagewidth = width;
		Common.Image.imageheight = height;
		Common.Image.showorginal = showorginal;
		
		var imagewidth = width;
		var imageheight = height;
		var winwidth = Common.Image.GetWinWidth() - 32;
		var winheight = Common.Image.GetWinHeight() - 32;

		width += 17;
		if (width > winwidth) {
			width = winwidth;
		}
		height += 41;
		if (height > winheight) {
			height = winheight;
			if ((width + 16) < winwidth) {
				width += 17;
			} else {
				width = winwidth;
			}
		}
		
		var newimagewidth = 0;
		var newimageheight = 0;

		// Try to fit the image to screen
		var innerwinwidth = width - 17;
		var innerwinheight = height - 41;
		if ((imagewidth / imageheight) >= (innerwinwidth /innerwinheight)) {
			newimagewidth = innerwinwidth;
			newimageheight = parseInt(imageheight * innerwinwidth / imagewidth);
		} else {
			newimagewidth = parseInt(imagewidth * innerwinheight / imageheight);
			newimageheight = innerwinheight;
		}
		
		if (newimagewidth == imagewidth && newimageheight == imageheight) {
			Modalbox.show('<div onclick="Modalbox.hide();"><img src="' + image_path + '" alt="' + title + '" /></div>', {title: title, width: width, height: height, transitions: false, showImageResize: false });
		} else {
			if (showorginal) {
				Modalbox.show('<div onclick="Modalbox.hide();"><img src="' + image_path + '" alt="' + title + '" /></div>', {title: title, width: width, height: height, transitions: false, showImageResize: true, imageResizeOrginal: showorginal, onImageResize: Common.Image.onImageResize });
			} else {
				width = newimagewidth;
				height = newimageheight;
				width += 17;
				height += 41;
				Modalbox.show('<div onclick="Modalbox.hide();"><img src="' + image_path + '" alt="' + title + '" width="' + newimagewidth + '" height="' + newimageheight + '" /></div>', {title: title, width: width, height: height, transitions: false, showImageResize: true, imageResizeOrginal: showorginal, onImageResize: Common.Image.onImageResize });
			}
		}
		return false;
	},
	GetWinWidth: function() {
		var winWidth = Element.getWidth(document.body);
		return winWidth;
	},
	GetWinHeight: function() {
		var winHeight;
		if (typeof window.innerHeight != 'undefined') {
			winHeight = window.innerHeight;
		} else if ( document.documentElement && typeof document.documentElement.clientHeight != 'undefined' && document.documentElement.clientHeight != 0 ) {
			winHeight = document.documentElement.clientHeight;
		} else if ( document.body && typeof document.body.clientHeight != 'undefined') {
			winHeight = document.body.clientHeight;
		}	
		return winHeight;
	}	
};

// * Input *******************************************************************************
// ***************************************************************************************

Common.Input = {
	MoveToEnd: function(element) {
		element = $(element);
		if (element.setSelectionRange) {
			var length = element.value.length;
			element.setSelectionRange(length, length);
		} else if (element.createTextRange) {
			 var range = element.createTextRange();
			 range.move("textedit");
			 range.select();
		}		
	},
	LimitText: function(element, limitNum) {
		element = $(element);
		if (element.value.length > limitNum) {
			element.value = element.value.substring(0, limitNum);
		}
	}	
	
};

// * InputInfo ***************************************************************************
// ***************************************************************************************

Common.InputInfo = {
	onMouseOver: function(element) {
		$(element).setStyle({
			cursor: 'pointer'}); 		
	},
	Toggle: function(info_element, focus_element) {
		focus_element = focus_element || null;
		
		info_element = $(info_element);
		
		if (info_element.style.display == 'none') {
			info_element.show();
		} else {
			info_element.hide();
		}
		
		if (focus_element != null) {
			$(focus_element).activate();
		}
		return false;
	}
};

// * SearchString ************************************************************************
// ***************************************************************************************

Common.SearchString = {
	Build: function(search_array) {
		var searchstring = '';
		if (search_array.constructor == Array) {
			var search_count = search_array.size();

			if (search_count > 0) {
				var first = true;
				for (i = (search_count - 1); i >= 0; i--) {
					if ((search_array[i] != '' && search_array[i] != '0') || !first) {
						first = false;
						searchstring = Common.SearchString.Escape(search_array[i]) + '/' + searchstring;
					}
				}
			}
		} else {
			searchstring = Common.SearchString.Escape(search_array);
		}
		return searchstring;
		
	},
	Escape: function(searchstring) {
		searchstring = searchstring.strip();
		searchstring = searchstring.replace(/[^a-zåäö0-9 +\-]+/ig, '');
		searchstring = searchstring.replace(/[ ]+/ig, '_');
		searchstring = encodeURIComponent(searchstring);
		if (searchstring == '' || searchstring == 0) {
			searchstring = '_';
		}
		return searchstring;
	}
};

// * dateFormat **************************************************************************
// ***************************************************************************************

/*
 * Date Format 1.2.2
 * (c) 2007-2008 Steven Levithan <stevenlevithan.com>
 * MIT license
 * Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal <cixar.com/~kris.kowal/>
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */
var dateFormat = function () {
	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && (typeof date == "string" || date instanceof String) && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date();
		if (isNaN(date)) throw new SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L > 99 ? Math.round(L / 10) : L),
				t:    H < 12 ? "a"  : "p",
				tt:   H < 12 ? "am" : "pm",
				T:    H < 12 ? "A"  : "P",
				TT:   H < 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
};


// * ObjTree *****************************************************************************
// ***************************************************************************************

Common.ObjTree = function () {
	return this;
};

//  object prototype

Common.ObjTree.prototype.attr_prefix = '-';

//  method: responseXML( responsexml )

Common.ObjTree.prototype.responseXML = function ( responsexml ) {
	if ( ! responsexml ) return;
	var root = responsexml.documentElement;

	return this.parseDOM( root );
};

//  method: parseXML( xmlsource )

Common.ObjTree.prototype.parseXML = function ( xml ) {
    var root;
    if ( window.DOMParser ) {
        var xmldom = new DOMParser();
//      xmldom.async = false;           // DOMParser is always sync-mode
        var dom = xmldom.parseFromString( xml, "application/xml" );
        if ( ! dom ) return;
        root = dom.documentElement;
    } else if ( window.ActiveXObject ) {
        xmldom = new ActiveXObject('Microsoft.XMLDOM');
        xmldom.async = false;
        xmldom.loadXML( xml );
        root = xmldom.documentElement;
    }
    if ( ! root ) return;
    return this.parseDOM( root );
};

//  method: parseDOM( documentroot )

Common.ObjTree.prototype.parseDOM = function ( root ) {
    if ( ! root ) return;

    this.__force_array = {};
    if ( this.force_array ) {
        for( var i=0; i<this.force_array.length; i++ ) {
            this.__force_array[this.force_array[i]] = 1;
        }
    }

    var json = this.parseElement( root );   // parse root node
    if ( this.__force_array[root.nodeName] ) {
        json = [ json ];
    }
    if ( root.nodeType != 11 ) {            // DOCUMENT_FRAGMENT_NODE
        var tmp = {};
        tmp[root.nodeName] = json;          // root nodeName
        json = tmp;
    }
    return json;
};

//  method: parseElement( element )

Common.ObjTree.prototype.parseElement = function ( elem ) {
    //  COMMENT_NODE
    if ( elem.nodeType == 7 ) {
        return;
    }

    //  TEXT_NODE CDATA_SECTION_NODE
    if ( elem.nodeType == 3 || elem.nodeType == 4 ) {
        var bool = elem.nodeValue.match( /[^\x00-\x20]/ );
        if ( bool == null ) return;     // ignore white spaces
        return elem.nodeValue;
    }

    var retval;
    var cnt = {};

    //  parse attributes
    if ( elem.attributes && elem.attributes.length ) {
        retval = {};
        for ( var i=0; i<elem.attributes.length; i++ ) {
            var key = elem.attributes[i].nodeName;
            if ( typeof(key) != "string" ) continue;
            var val = elem.attributes[i].nodeValue;
            if ( ! val ) continue;
            key = this.attr_prefix + key;
            if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
            cnt[key] ++;
            this.addNode( retval, key, cnt[key], val );
        }
    }

    //  parse child nodes (recursive)
    if ( elem.childNodes && elem.childNodes.length ) {
        var textonly = true;
        if ( retval ) textonly = false;        // some attributes exists
        for ( var i=0; i<elem.childNodes.length && textonly; i++ ) {
            var ntype = elem.childNodes[i].nodeType;
            if ( ntype == 3 || ntype == 4 ) continue;
            textonly = false;
        }
        if ( textonly ) {
            if ( ! retval ) retval = "";
            for ( var i=0; i<elem.childNodes.length; i++ ) {
                retval += elem.childNodes[i].nodeValue;
            }
        } else {
            if ( ! retval ) retval = {};
            for ( var i=0; i<elem.childNodes.length; i++ ) {
                var key = elem.childNodes[i].nodeName;
                if ( typeof(key) != "string" ) continue;
                var val = this.parseElement( elem.childNodes[i] );
                if ( ! val ) continue;
                if ( typeof( val ) == "string" ) val = this.xml_escape( val );
                if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
                cnt[key] ++;
                this.addNode( retval, key, cnt[key], val );
            }
        }
    }
    return retval;
};

//  method: addNode( hash, key, count, value )

Common.ObjTree.prototype.addNode = function ( hash, key, cnts, val ) {
    if ( this.__force_array[key] ) {
        if ( cnts == 1 ) hash[key] = [];
        hash[key][hash[key].length] = val;      // push
    } else if ( cnts == 1 ) {                   // 1st sibling
        hash[key] = val;
    } else if ( cnts == 2 ) {                   // 2nd sibling
        hash[key] = [ hash[key], val ];
    } else {                                    // 3rd sibling and more
        hash[key][hash[key].length] = val;
    }
};

//  method: xml_escape( text )

Common.ObjTree.prototype.xml_escape = function ( text ) {
	return String(text).replace('{/and/}', '&').replace('{/less/}', '<').replace('{/more/}', '>').replace('{/quote/}', '\'').replace('{/dquote/}', '\"');
};

// * InputInfo ***************************************************************************
// ***************************************************************************************

Common.SpanLink = {
	Empty: function() {
		return false;
	},	
	onMouseOver: function(element) {
		$(element).setStyle({
			cursor: 'pointer'});
	},
	onMouseOverNormal: function(event) {
		event = event || window.event
		var element = Event.element(event);
		$(element).setStyle({
			cursor: 'auto'});
	}
};


// * Textarea *********************************************************Ä******************
// ***************************************************************************************

Common.Textarea = {
	clientpc: '',
	clientver: '',
	is_ie: false,
	is_win: false,
	baseheight: null,
	theselection: false,
	CaretPosition: function() {
		var start = null;
		var end = null;
	},
	GetCaretPosition: function(element) {
		var caretPos = new Common.Textarea.CaretPosition();
		
		if(element.selectionStart || element.selectionStart == 0) {
			caretPos.start = element.selectionStart;
			caretPos.end = element.selectionEnd;
		} else if(document.selection) {
		
			var range = document.selection.createRange();
			var range_all = document.body.createTextRange();
			range_all.moveToElementText(element);
			
			var sel_start;
			for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) {		
				range_all.moveStart('character', 1);
			}
		
			element.sel_start = sel_start;
		
			caretPos.start = element.sel_start;
			caretPos.end = element.sel_start;			
		}

		return caretPos;
	},
	InsertBBCode: function(element, bbopen, bbclose) {
		Common.Textarea.theselection = false;
		element.focus();
		
		if ((Common.Textarea.clientver >= 4) && Common.Textarea.is_ie && Common.Textarea.is_win) {
			Common.Textarea.theselection = document.selection.createRange().text;

			if (Common.Textarea.theselection)	{
				document.selection.createRange().text = bbopen + Common.Textarea.theselection + bbclose;
				element.focus();
				Common.Textarea.theselection = '';
				return;
			}
		} else if (element.selectionEnd && (element.selectionEnd - element.selectionStart > 0)) {
			Common.Textarea.MozWrap(element, bbopen, bbclose);
			element.focus();
			Common.Textarea.theselection = '';
			return;
		}
		
		var caret_pos = Common.Textarea.GetCaretPosition(element).start;
		var new_pos = caret_pos + bbopen.length;		

		Common.Textarea.InsertText(element, bbopen + bbclose);

		if (!isNaN(element.selectionStart)) {
			element.selectionStart = new_pos;
			element.selectionEnd = new_pos;
		}	else if (document.selection) {
			var range = element.createTextRange(); 
			range.move("character", new_pos); 
			range.select();
			Common.Textarea.StoreCaret(element);
		}

		element.focus();
		return;
	},
	InitBase: function(element) {
		Common.Textarea.clientpc = navigator.userAgent.toLowerCase();
		Common.Textarea.clientver = parseInt(navigator.appVersion); // Get browser version

		Common.Textarea.is_ie = ((Common.Textarea.clientpc.indexOf('msie') != -1) && (Common.Textarea.clientpc.indexOf('opera') == -1));
		Common.Textarea.is_win = ((Common.Textarea.clientpc.indexOf('win') != -1) || (Common.Textarea.clientpc.indexOf('16bit') != -1));

		if (Common.Textarea.is_ie && typeof(Common.Textarea.baseheight) != 'number') {
			element.focus();
			Common.Textarea.baseheight = document.selection.createRange().duplicate().boundingHeight;
		}	
	},
	InsertText: function(element, text) {
		if (!isNaN(element.selectionStart)) {
			var sel_start = element.selectionStart;
			var sel_end = element.selectionEnd;

			Common.Textarea.MozWrap(element, text, '')
			element.selectionStart = sel_start + text.length;
			element.selectionEnd = sel_end + text.length;
		} else if (element.createTextRange && element.caretPos) {
			if (Common.Textarea.baseheight != element.caretPos.boundingHeight) {
				element.focus();
				Common.Textarea.StoreCaret(element);
			}

			var caret_pos = element.caretPos;
			caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) == ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text;
		} else {
			element.value = element.value + text;
		}
		element.focus();
	},
	MakePrivate: function(element, arrow_element, arrow_location, is_private) {
		if (is_private) {
			$(element).setStyle({
				background: '#EBF7D2'});
			
			if (arrow_element !== undefined) {
				if (arrow_location == 'up') {
					$(arrow_element).src = '/images/profile/textarea/arrow_private.gif';
				} else if (arrow_location == 'left') {
					$(arrow_element).src = '/images/profile/gb/arrow_private.gif';
				}
			}
				
		} else {
			$(element).setStyle({
				background: '#fff'});

			if (arrow_element !== undefined) {
				if (arrow_location == 'up') {
					$(arrow_element).src = '/images/profile/textarea/arrow.gif';
				} else if (arrow_location == 'left') {
					$(arrow_element).src = '/images/profile/gb/arrow_private.gif';
				}
			}
		}
	},
	MozWrap: function(element, open, close) {
		var selLength = element.textLength;
		var selStart = element.selectionStart;
		var selEnd = element.selectionEnd;
		var scrollTop = element.scrollTop;

		if (selEnd == 1 || selEnd == 2) {
			selEnd = selLength;
		}

		var s1 = (element.value).substring(0,selStart);
		var s2 = (element.value).substring(selStart, selEnd)
		var s3 = (element.value).substring(selEnd, selLength);

		element.value = s1 + open + s2 + close + s3;
		element.selectionStart = selEnd + open.length + close.length;
		element.selectionEnd = element.selectionStart;
		element.focus();
		element.scrollTop = scrollTop;

		return;
	},
	StoreCaret: function(element) {
		if (element.createTextRange) {
			element.caretPos = document.selection.createRange().duplicate();
		}
	}
};


// * Uploader ****************************************************************************
// ***************************************************************************************
Common.Uploader = Class.create();
Common.Uploader.prototype = {
	appendPostData: function() {
		var form_elements = [];
		var parameters = this.options.parameters;
		var i = 0;
		for (var name in parameters) {
			form_elements[i] = document.createElement('input');
			form_elements[i].type = 'hidden';
			form_elements[i].name = name;
			form_elements[i].value = parameters[name];
			this.form.appendChild(form_elements[i]);
			i++;
		}

		return form_elements;
	},
	createFrame: function() {
		var frame_id = 'upload-gaddad-temp';
		var io;
		if (window.ActiveXObject) {
			io = document.createElement('<iframe id="' + frame_id + '" name="' + frame_id + '" />');
			io.src = 'javascript:false';
		} else {
			io = document.createElement('iframe');
			io.id = frame_id;
			io.name = frame_id;
		}

		io.style.position = 'absolute';
		io.style.top = '-1000px';
		io.style.left = '-1000px';

		document.body.appendChild(io);
	},
	getTransport: function() {
		var transport = {};
		return transport;
	},
	hasOwnProperty: function(obj, prop) {
		if (Object.prototype.hasOwnProperty) {
			return obj.hasOwnProperty(prop);
		}

		return !this.isUndefined(obj[prop]) && obj.constructor.prototype[prop] !== obj[prop];
	},
	initialize: function(form, url, options) {
		this.transport = this.getTransport();
		this.setOptions(options);
		this.form = $(form);
		this.upload(url);
	},
	isUndefined: function(obj) {
		return typeof obj === 'undefined';
	},
	setOptions: function(options) {
		this.options = {
      parameters: ''
    }
    Object.extend(this.options, options || {});

    if (typeof this.options.parameters == 'string')
      this.options.parameters = this.options.parameters.toQueryParams();
	},
	startIndicator: function() {
		if(this.options.indicator) {
			Element.show(this.options.indicator);
		}
	},
	stopIndicator: function() {
		if(this.options.indicator) {
			Element.hide(this.options.indicator);
		}
	},
	upload: function(url) {
		this.startIndicator();

		// Create iframe in preparation for file upload.
		this.createFrame();

		var frame_id = 'upload-gaddad-temp';
		var upload_encoding = 'multipart/form-data';
		var oconn = this;
		var io = $(frame_id);

		// Track original HTML form attribute values.
		var raw_form_attributes = {
			action: this.form.getAttribute('action'),
			method: this.form.getAttribute('method'),
			target: this.form.getAttribute('target')
		};

		// Initialize the HTML form properties in case they are not defined in the HTML form.
		this.form.setAttribute('action', url);
		this.form.setAttribute('method', 'POST');
		this.form.setAttribute('target', frame_id);

		if(this.form.encoding) {
			// IE does not respect property enctype for HTML forms.
			// Instead it uses the property - "encoding".
			this.form.setAttribute('encoding', upload_encoding);
		}
		this.form.setAttribute('enctype', upload_encoding);

		var form_elements = null;
		if (this.options.parameters) {
			// Create hidden variables for the parameters
			form_elements = this.appendPostData();
		}

		// Start file upload.
		this.form.submit();

		// Remove hidden input created from parameters
		if (form_elements && form_elements.length > 0) {
			for (var i = 0; i < form_elements.length; i++) {
				this.form.removeChild(form_elements[i]);
			}
		}

		// Restore HTML form attributes to their original values prior to file upload.
		for (var prop in raw_form_attributes){
			if (this.hasOwnProperty(raw_form_attributes, prop)) {
				if (raw_form_attributes[prop]) {
					this.form.setAttribute(prop, raw_form_attributes[prop]);
				} else {
					this.form.removeAttribute(prop);
				}
			}
		}

		// Create the upload callback handler that fires when the iframe
		// receives the load event.  Subsequently, the event handler is detached
		// and the iframe removed from the document.
		var upload_callback = function() {
			try {
				// responseText and responseXML will be populated with the same data from the iframe.
				// Since the HTTP headers cannot be read from the iframe
				oconn.transport.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : io.contentWindow.document.documentElement.textContent;
				oconn.transport.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
			}
			catch(e){}

			if (oconn.options.onComplete) {
				oconn.options.onComplete(oconn.transport);
			}

			Event.stopObserving(io, "load", upload_callback);

			setTimeout(
				function(){
					document.body.removeChild(io);
					oconn.stopIndicator();
				}, 100);
		};

		Event.observe(io, "load", upload_callback)
	}
};
