var sAgent = navigator.userAgent.toLowerCase();
var is_ie = (sAgent.indexOf("msie") != -1);
var is_ie7 = (sAgent.indexOf("msie 7") != -1);
var is_gecko = !is_ie;
var is_safari = (sAgent.indexOf("safari") != -1);
var is_nav	= (sAgent.indexOf("netscape") != -1);

if (is_ie) {
    try {
        document.execCommand("BackgroundImageCache", false, true);
    } catch(e) {};
}

var randomGenerator = {
    d: new Date(),
    seed: null,
    A: 48271,
    M: 2147483647,
    Q: null,
    R: null,
    oneOverM: null,
    
    generate: function(lnr, unr) {
        if (this.seed == null)
            this.seed = 2345678901 + (this.d.getSeconds() * 0xFFFFFF) + (this.d.getMinutes() * 0xFFFF);
        this.Q = this.M / this.A;
        this.R = this.M % this.A;
        this.oneOverM = 1.0 / this.M;
        return Math.floor((unr - lnr + 1) * this.next() + lnr);
    },
    
    next: function() {
        var hi = this.seed / this.Q;
        var lo = this.seed % this.Q;
        var test = this.A * lo - this.R * hi;
        if (test > 0)
            this.seed = test;
        else
            this.seed = test + this.M;
        return (this.seed * this.oneOverM);
    }
};

Object.extend(String.prototype, {
    appendRandomNumber: function(length) {
        var source = this;
        for (var i = 1; i <= length; i++) {
            source += randomGenerator.generate(1, 9);
        }
        return source;
    },
    prependRandomNumber: function(length) {
        var source = this;
        for (var i = 1; i <= length; i++) {
            source = randomGenerator.generate(1, 9) + source;
        }
        return source;
    },
    sprintf: function() {
        var str = this;
    	var ar = arguments;
    	var i=0,inx = str.indexOf("%s");
    	while(inx >= 0) {
    		str = str.substr(0, inx) + ar[i++] + str.substr(inx+2);
    		inx = str.indexOf("%s");
    	}
    	return str;
    },
    parseColor: function() {  
      var color = '#';  
      if(this.slice(0,4) == 'rgb(') {  
        var cols = this.slice(4,this.length-1).split(',');  
        var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
      } else {  
        if(this.slice(0,1) == '#') {  
          if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
          if(this.length==7) color = this.toLowerCase();  
        }  
      }  
      return(color.length==7 ? color : (arguments[0] || this));  
    },
    hash: function() {
        var str = this;
        str = str.toLowerCase();
        var hash1 = hash2 = result = 0;
        for (var i = 0; i <= str.length; ++i ) {
            hash1 ^= str.charCodeAt(i);
            if (i != str.length)
                hash2 ^= str.charCodeAt(++i);
        }
        result = (hash1 << 8) | hash2;
        return result;
    },
    md5: function() {
        var prefix = arguments.length > 0 ? arguments[0] : "";
        var postfix = arguments.length > 1 ? arguments[1] : "";
        if (Crypt && Crypt.MD5)
            return Crypt.MD5.hex_md5(prefix + this + postfix);
        else
            return prefix + this + postfix;
    }
});

Object.extend(Array.prototype, {
   remove: function(dx) {
       return this.splice(dx,1);
   },
   removeItem: function(item) {
      for ( var i = 0 ; i < this.length ; i++ )
         if ( this[i] == item ) {
            this.remove(i);
            break;
         }
   },
	/**
	 * Compare this array to the argument, only works for *indexed* arrays
	 * @author Menno van Slooten (mvanslooten AT ebuddy.com)
	 * @param {Array} a
	 * @type boolean
	 */
   equals: function(a) {
		if(typeof this.length == 'undefined') return false;
		else if(this.length != a.length) return false;
		var equals = true;
		for(var i=0; i<this.length; i++) {
			if(typeof this[i] != typeof a[i]) equals = false;
			else if(typeof this[i] == 'object' && this[i].length && a[i].length) {
				equals = this[i].equals(a[i]);
			}
			else if(this[i] != a[i]) equals = false;
			if(!equals) return false;
		}
		return true;
	}
   
});

if (!document.getElementsByAttribute) {
// [string attributeName],[string attributeValue]
    document.getElementsByAttribute = function(attrN, attrV) {
        var oIterate = document.getElementsByTagName('*'), aResponse = new Array(), attr, elm, i = 0;
        while ((elm = oIterate.item(i))) {
            attr = elm.getAttributeNode(attrN);
            if (attr) {
                if (typeof attrV != "undefined") {
                    if (attr.value == attrV) aResponse.push(elm);
                } else {
                    aResponse.push(elm);
                }
            }
            i++;
        }
        return aResponse;
    };
}

document.getButtonById = function(id) {
    return Button.cache[id] || null;
};
document.getButtonsByGroup = function(group) {
    return Button.groupCache[group] || [];
};
document.getComboboxById = function(id) {
    return ComboBox.cache[id] || null;
};
document.getComboboxesByGroup = function(group) {
    return ComboBox.groupCache[group] || [];
};
document.getCheckboxById = function(id) {
    return Checkbox.cache[id] || null;
};
document.getCheckboxesByGroup = function(group) {
    return Checkbox.groupCache[group] || [];
};
document.getEditorById = function(id) {
    var editors = this.getElementsByAttribute('rico:widget', 'editor');
    for (var i = 0; i < editors.length; i++)
        if (editors[i].editor.getId() == id)
            return editors[i].editor;
    return null;
};
document.getAccordionById = function(id) {
    var tabs = this.getElementsByAttribute('rico:widget', 'accordionTab');
    for (var i = 0; i < tabs.length; i++)
        if (tabs[i].accordiontab.id == id)
            return tabs[i].accordiontab;
    return null;
};
document.purgeButtonCache = function() {
    var i, j;
    for (i = 0; i < Button.cache.length; i++)
        if (!(Button.cache[i].domNode && Button.cache[i].domNode.parentNode))
            Button.cache.remove(i);
    for (j = 0; j < Button.groupCache.length; j++)
        document.purgeButtonGroupCache(j);
}
document.purgeButtonGroupCache = function(group) {
    if (Button.groupCache[group]) {
        for (i = 0; i < Button.groupCache[group].length; i++)
            if (!(Button.groupCache[group][i].domNode && Button.groupCache[group][i].domNode.parentNode))
                Button.groupCache[group].remove(i);
        if (Button.groupCache[group].length == 0) Button.groupCache.remove(group);
    }
}

document.changeLocale = function(locale) {
    if (Core && Core.Settings) Core.Settings.setCookie('language', locale);
    for (var i = 0; i < Button.cache.length; i++)
       Button.cache[i].fireEvent('changeLocale', locale);
    for (var j = 0; j < ComboBox.cache.length; j++)
       ComboBox.cache[j].fireEvent('changeLocale', locale);
    var labels = this.getElementsByAttribute('rico:widget', 'label');
    for (var k = 0; k < labels.length; k++)
       labels[k].innerHTML = _(labels[k].getAttribute('rico:localekey'));
};

document.changeTheme = function(theme, isDefault) {
    var i;
    for (i = 0; i < ComboBox.cache.length; i++)
       ComboBox.cache[i].fireEvent('changeTheme', theme, isDefault);
    var editors = this.getElementsByAttribute('rico:widget', 'editor');
    for (i = 0; i < editors.length; i++)
       editors[i].editor.fireEvent('changeTheme', theme, isDefault);
    var uploaders = document.getElementsByAttribute('rico:widget', 'uploader');
    for (i = 0; i < uploaders.length; i++)
       uploaders[i].uploader.fireEvent('changeTheme', theme, isDefault);
};

function empty(obj) {
    if(obj == null || typeof(obj) == "undefined" || obj == "" || obj == "undefined") {
        return true;
    } else {
        return false;
    }
};

function trim(str) {
   return str.replace(/^\s*|\s*$/g,"");
};

function URLEncode(sStr) {
    return escape(sStr).replace("/\+/g", '%2C').replace("/\"/g",'%22').replace("/\'/g", '%27');
};

function encodeHTML(htmlBuffer) {
	if (htmlBuffer == null)
		return null;
	var encodedHtml = htmlBuffer;
	encodedHtml = encodedHtml.replace(/&/g,"&amp;");
	encodedHtml = encodedHtml.replace(/</g,"&lt;");
	encodedHtml = encodedHtml.replace(/>/g,"&gt;");
	encodedHtml = encodedHtml.replace(/"/g,"&quot;");
	encodedHtml = encodedHtml.replace(/'/g,"&apos;");
	return encodedHtml;
};

function encodeHTMLOnly(html) {
    if (html == null) return null;
    html = html.replace(/<(?!\/?span|\/?font|\/?b|\/?strong|\/?u|\/?em|\/?i|\/?strike|\/?a|\/?img|br|:-p|\):\))/gi, "&#60;");
    html = html.replace(/([^(?!span|font|b|strong|u|em|i|strike|a|img|br\s\/?|\"|\')])+>/gi, "$1&#62;");
    return html;
};

function decodeHTML(encodedBuffer) {
	if (encodedBuffer == null)
		return null;
	var decodedHtml = encodedBuffer;
	decodedHtml = decodedHtml.replace(/&#38;|&amp;/g,"&");
	decodedHtml = decodedHtml.replace(/&#60;|&lt;/g,"<");
	decodedHtml = decodedHtml.replace(/&#62;|&gt;/g,">");
	decodedHtml = decodedHtml.replace(/&#34;|&quot;/g,"\"");
	decodedHtml = decodedHtml.replace(/&#39;|&apos;/g,"'");
	return decodedHtml;
};

function decode_utf8(utftext) {
	var plaintext = ""; var i=0; var c=c1=c2=0;
	while(i < utftext.length) {
		c = utftext.charCodeAt(i);
		if (c < 128) {
		    if (c == 13)
		        plaintext += "\n";
		    else
			    plaintext += String.fromCharCode(c);
			i++;
		} else if((c > 191) && (c < 224)) {
			c2 = utftext.charCodeAt(i+1);
			plaintext += String.fromCharCode(((c&31)<<6) | (c2&63));
			i += 2;
		} else {
			c2 = utftext.charCodeAt(i+1);
			c3 = utftext.charCodeAt(i+2);
			plaintext += String.fromCharCode(((c&15)<<12) | ((c2&63)<<6) | (c3&63));
			i += 3;
		}
	}
	return plaintext;
};

function JScriptEscapeString(s) {
	s = s.replace(/([\\])/g, "\\x5C");
	s = s.replace(/(['])/g, "\\x27");
	s = s.replace(/(["])/g, "\\x22");
	return s;
};

function JScriptEscapeURIComponent(s) {
	s = encodeURIComponent(s);
	s = s.replace(/(['])/g, "%27");
	s = s.replace(/(["])/g, "%22");
	s = s.replace(/([\\])/g, "%5C");
	return s;
};

function instanceOf(object, constructor) {
   while (object != null) {
      if (object == constructor.prototype)
         return true;
      object = object.__proto__;
   }
   return false;
};

Object.extend(Element, {
    getOpacity: function(element){  
      var opacity;
      if (opacity = Element.getStyle(element, 'opacity'))  
        return parseFloat(opacity);  
      if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))  
        if(opacity[1]) return parseFloat(opacity[1]) / 100;  
      return 1.0;  
    },
    
    setOpacity: function(element, value){  
      element= $(element);  
      if (value == 1){
        Element.setStyle(element, { opacity: 
          (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 
          0.999999 : null });
        if(/MSIE/.test(navigator.userAgent))  
          Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});  
      } else {  
        if(value < 0.00001) value = 0;  
        Element.setStyle(element, {opacity: value});
        if(/MSIE/.test(navigator.userAgent))  
         Element.setStyle(element, 
           { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
                     'alpha(opacity='+value*100+')' });  
      }
    },
    
    Center: function(element, mode) {
        if (typeof mode == "undefined") mode = 3;
        element = $(element);
        var my_width  = 0;
        var my_height = 0;
        if ( typeof( window.innerWidth ) == 'number' ) {
            my_width  = window.innerWidth;
            my_height = window.innerHeight;
        } else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
            my_width  = document.documentElement.clientWidth;
            my_height = document.documentElement.clientHeight;
        } else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
            my_width  = document.body.clientWidth;
            my_height = document.body.clientHeight;
        }
        element.style.position = 'absolute';
        element.style.display  = 'block';
        //element.style.zIndex   = 99;
        var scrollY = 0;
        if ( document.documentElement && document.documentElement.scrollTop )
            scrollY = document.documentElement.scrollTop;
        else if ( document.body && document.body.scrollTop )
            scrollY = document.body.scrollTop;
        else if ( window.pageYOffset )
            scrollY = window.pageYOffset;
        else if ( window.scrollY )
            scrollY = window.scrollY;
        var elementDimensions = Element.getDimensions(element);
        var setX = ( my_width  - elementDimensions.width  ) / 2;
        var setY = ( my_height - elementDimensions.height ) / 2 + scrollY;
        setX = ( setX < 0 ) ? 0 : setX;
        setY = ( setY < 0 ) ? 0 : setY;
        if (mode == 1 || mode == 3)
            element.style.left = setX + "px";
        if (mode == 2 || mode == 3)
            element.style.top  = setY + "px";
        return {dims: elementDimensions, x: setX, y: setY};
    }
});

function appendStyleSheet(documentElement, cssFileUrl) {
	if (is_ie)
		return documentElement.createStyleSheet( cssFileUrl ) ;
	else {
		var e = documentElement.createElement('LINK');
		e.rel  = 'stylesheet';
		e.type = 'text/css';
		e.href = cssFileUrl;
		documentElement.getElementsByTagName("HEAD")[0].appendChild(e);
		return e ;
	}
};

function getElementPosition(el, relativeWindow) {
	// Initializes the Coordinates object that will be returned by the function.
	var c = { X:0, Y:0 } ;
	var oWindow = relativeWindow || window ;
	// Loop throw the offset chain.
	while (el) {
		c.X += el.offsetLeft ;
		c.Y += el.offsetTop ;
		if (el.offsetParent == null) {
			var oOwnerWindow = getElementWindow( el ) ;
			if ( oOwnerWindow != oWindow )
				el = oOwnerWindow.frameElement ;
			else
				break ;
		} else
			el = el.offsetParent ;
	}
	// Return the Coordinates object
	return c ;
};

function getElementWindow(element) {
	var oDocument = element.ownerDocument || element.document ;
	// With Safari, there is not way to retrieve the window from the document, so we must fix it.
	if ( is_safari && !oDocument.parentWindow )
		FixDocumentParentWindow( window.top ) ;
	return oDocument.parentWindow || oDocument.defaultView ;
};

/**
 * This is a Safari specific function that fix the reference to the parent
 * window from the document object.
*/
function fixDocumentParentWindow(targetWindow) {
	targetWindow.document.parentWindow = targetWindow ;
	for ( var i = 0 ; i < targetWindow.frames.length ; i++ )
		fixDocumentParentWindow( targetWindow.frames[i] ) ;
};

function DEBUG(msg) {
	if (Core.DEBUG) {
	    if (!empty(Core.DEBUGWIN) && !Core.DEBUGWIN.closed
	      && Core.DEBUGWIN.document && Core.DEBUGWIN.document.body) {
	    	msg = encodeHTML(msg).replace(/\n/g, "<br/>\n");
	    	/*msg = msg.replace(/\s+([\d]+?):/g, '<strong>$1</strong>:');
	    	msg = msg.replace(/([:;])([\w\d]+?)=/g, '$1<em>$2</em>=');
	    	msg = msg.replace(/=(.+?);/g, '=<strong>$1</strong>;');*/
            var msgContainer = Core.DEBUGWIN.document.createElement('div');
            msgContainer.innerHTML = '<div class="Timestamp">' + new Date().toGMTString() + '</div>' + msg;
            msgContainer.className = 'Message';
	        Core.DEBUGWIN.document.body.appendChild(msgContainer);
	    }
	}
};

function PROFILE(msg) {
	if (Core.PROFILE) {
	    if (!empty(Core.PROFILEWIN) && !Core.PROFILEWIN.closed
	      && Core.PROFILEWIN.document && Core.PROFILEWIN.document.body) {
	    	msg = msg.replace(/\n/g, "<br/>\n");
            var msgContainer = Core.PROFILEWIN.document.createElement('div');
            msgContainer.innerHTML = msg;
            msgContainer.className = 'Message';
	        Core.PROFILEWIN.document.body.appendChild(msgContainer);
	    }
	}
};

function _(s) {
    if (EmsnSettings.language && (Core && EmsnLanguage[Core.Settings.language]) && !empty(EmsnLanguage[Core.Settings.language][s]))
      return EmsnLanguage[Core.Settings.language][s];
    else
      return EmsnLanguage['en_GB'][s];
};

function _translateNode(node, newvalue) {
    if (node.nodeType == 3)
        node.nodeValue = newvalue;
    else if (node.childNodes && node.childNodes.length > 0)
       for (var i = 0; i < node.childNodes[i].length; i++)
           _translateNode(node.childNodes[i]);
};

function getElementsByNodeType(oRoot, type) { 
    var aNodes = []; 
    var oNode; 
    for(var i = 0; i < oRoot.childNodes.length; i++) { 
        oNode = oRoot.childNodes[i]; 
        if(oNode.nodeType == type) aNodes.push(oNode) 
        if(oNode.hasChildNodes()) { 
            aNodes = aNodes.concat(getElementsByNodeType(oNode, type)) 
        } 
    }   
    return aNodes; 
}

