/**
 * eCommunities ECMS Tools Class 
 * @author Kevin Farley
 * @version 2.0
 */

// Declare the required ECMS namespaces if they do not already exist
if (ECMS == null || typeof(ECMS) != "object") { var ECMS = new Object(); }

if (ECMS.ECORE == null || typeof(ECMS.ECORE) != "object") { ECMS.ECORE = new Object(); }
if (ECMS.ECORE.tools == null || typeof(ECMS.ECORE.tools) != "object") { ECMS.ECORE.tools = new Object(); }

ECMS.ECORE.tools = {

	charCounter: function (fid,maxchars) {
		var counter = document.getElementById(fid+'_counter');
		var txtField = document.getElementById(fid);
		if (txtField.value.length > maxchars) {
			txtField.value = txtField.value.substring(0, maxchars);
		} else {
			counter.value = maxchars - txtField.value.length;
		}
	},
	
	objectLength: function (obj) {
		var propCount = 0;
		for (var prop in obj) {
			propCount++;
		}
		return propCount;
	},
	
	showHideDiv: function (box,id) {
		var elm = document.getElementById(id);
		elm.style.display = box.checked? "block":"none";
	},

	showDiv: function(id) {
		var elm = document.getElementById(id)
		elm.style.display = "block"
	},

	hideDiv: function(id) {
		var elm = document.getElementById(id)
		elm.style.display = "none"
	},

	toggleDiv: function (thisId,thatId,expand,collapse) {
		var elm = document.getElementById(thatId);
		if (elm.style.display == 'none') {
			elm.style.display = 'block';
			thisId.src = collapse;
		} else {
			elm.style.display = 'none';
			thisId.src = expand;
		}
	},

	addslashes: function ( str ) {
	    return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0");
	},

	stripslashes: function ( str ) {
		return (str+'').replace(/\0/g, '0').replace(/\\([\\'"])/g, '$1');
	},
	
	strip_tags: function(str, allowed_tags) {
	    // Strips HTML and PHP tags from a string  
	    // 
	    // version: 909.322
	    // discuss at: http://phpjs.org/functions/strip_tags    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Luke Godfrey
	    // +      input by: Pul
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Onno Marsman    // +      input by: Alex
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: Marc Palau
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: Brett Zamir (http://brett-zamir.me)    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Eric Nagel
	    // +      input by: Bobby Drake
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Tomasz Wesolowski    // *     example 1: strip_tags('<p>Kevin</p> <b>van</b> <i>Zonneveld</i>', '<i><b>');
	    // *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
	    // *     example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
	    // *     returns 2: '<p>Kevin van Zonneveld</p>'
	    // *     example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");    // *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
	    // *     example 4: strip_tags('1 < 5 5 > 1');
	    // *     returns 4: '1 < 5 5 > 1'
	    var key = '', allowed = false;
	    var matches = [];    var allowed_array = [];
	    var allowed_tag = '';
	    var i = 0;
	    var k = '';
	    var html = ''; 
	    var replacer = function (search, replace, str) {
	        return str.split(search).join(replace);
	    };
	     // Build allowes tags associative array
	    if (allowed_tags) {
	        allowed_array = allowed_tags.match(/([a-zA-Z0-9]+)/gi);
	    }
	     str += '';
	 
	    // Match tags
	    matches = str.match(/(<\/?[\S][^>]*>)/gi);
	     // Go through all HTML tags
	    for (key in matches) {
	        if (isNaN(key)) {
	            // IE7 Hack
	            continue;        }
	 
	        // Save HTML tag
	        html = matches[key].toString();
	         // Is tag not in allowed list? Remove from str!
	        allowed = false;
	 
	        // Go through all allowed tags
	        for (k in allowed_array) {            // Init
	            allowed_tag = allowed_array[k];
	            i = -1;
	 
	            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}
	            if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag)   ;}
	 
	            // Determine
	            if (i == 0) {
	            	allowed = true;
	                break;
	            }
	        }
	         if (!allowed) { 
	            str = replacer(html, "", str); // Custom replace. No regexing
	        }
	    }
	     return str;
	},
	
	trim: function(str, charlist) {
	    // Strips whitespace from the beginning and end of a string  
	    // 
	    // version: 909.322
	    // discuss at: http://phpjs.org/functions/trim    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: mdsjack (http://www.mdsjack.bo.it)
	    // +   improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev)
	    // +      input by: Erkekjetter
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)    // +      input by: DxGx
	    // +   improved by: Steven Levithan (http://blog.stevenlevithan.com)
	    // +    tweaked by: Jack
	    // +   bugfixed by: Onno Marsman
	    // *     example 1: trim('    Kevin van Zonneveld    ');    // *     returns 1: 'Kevin van Zonneveld'
	    // *     example 2: trim('Hello World', 'Hdle');
	    // *     returns 2: 'o Wor'
	    // *     example 3: trim(16, 1);
	    // *     returns 3: 6    var whitespace, l = 0, i = 0;
	    str += '';
	    
	    if (!charlist) {
	        // default list        
	    	whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
	    } else {
	        // preg_quote custom list
	        charlist += '';
	        whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');    
	    }
	    
	    l = str.length;
	    for (i = 0; i < l; i++) {
	        if (whitespace.indexOf(str.charAt(i)) === -1) {            
	        	str = str.substring(i);
	            break;
	        }
	    }
	        l = str.length;
	    for (i = l - 1; i >= 0; i--) {
	        if (whitespace.indexOf(str.charAt(i)) === -1) {
	            str = str.substring(0, i + 1);
	            break;        }
	    }
	    
	    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
	},
	
	expandEditor: function(editorID) {
		// First hide all of the main forms content.
		var mainForm = document.getElementById('ECMS_form');
		mainForm.style.overflow = 'hidden';
		
		// Then maximize the editor into the form space and give it focus.
		var pm = document.getElementById(editorID);
		pm.className = 'ECMS_fullScreenEditor';
		pm.focus();
		
		// Finally switch any editor headers appropriately.
		var headWindow = document.getElementById(editorID+'_window');
		headWindow.style.display = 'none';
		
		var headFull = document.getElementById(editorID+'_fullscreen');
		headFull.style.display = 'block';		
	},	

	reduceEditor: function(editorID,classID) {
		// First restore the editor content to it's original size.
		var pm = document.getElementById(editorID);
		pm.className = classID;
		
		// Next switch any editor headers appropriately.
		var headWindow = document.getElementById(editorID+'_window');
		headWindow.style.display = 'block';
		
		var headFull = document.getElementById(editorID+'_fullscreen');
		headFull.style.display = 'none';
		
		// Lastly restore the main forms content.
		var mainForm = document.getElementById('ECMS_form');
		mainForm.style.overflow = 'visible';
	},	

	addElement: function () {
		var parentDiv = document.getElementById('ECMS_fileList');
		var counter = document.getElementById('ECMS_fileCounter');
		var maxFiles = document.getElementById('ECMS_fileMax').value;
		var fileCount = document.getElementsByName('ECMS_fileContainer').length;

		if (parseInt(maxFiles) > parseInt(fileCount)) {
		
			var num = (document.getElementById("ECMS_fileCounter").value -1)+ 2;
			counter.value = num;
			
			var divIdName = "file"+num+"_container";
			var newdiv = document.createElement('div');
			newdiv.setAttribute("name","ECMS_fileContainer");
			
			newdiv.setAttribute("id",divIdName);
			newdiv.innerHTML = '<div class="ECMS_formSection" style="margin-top:30px;">Select Media File ' + num + ' (<span class="ECMS_jsLink body-small-c" onclick="ECORE_removeElement(\'' + divIdName + '\')">remove</span>)</div><div class="ECMS_formRow"><div class="ECMS_formLeft">Media File ' + num + ':</div><div class="ECMS_formRight"><input name="file' + num + '" type="file" id="file' + num + '" class="ECMS_formField" size="40" /></div></div><div class="ECMS_formRow"><div class="ECMS_formLeft">Alternate File ' + num + ' Name:</div><div class="ECMS_formRight"><input name="file' + num + 'name" type="text" id="file' + num + 'name" class="ECMS_formField" size="40" /></div></div><div style="height:25px;">&nbsp;</div></div>';
		
			parentDiv.appendChild(newdiv);
			
		} else {
			alert('You can upload a maximum of only ' + maxFiles + ' file(s) at this time.');
		}
	},

	removeElement: function (divID) {
		var parentDiv = document.getElementById('ECMS_fileList');
		var remDiv = document.getElementById(divID);

		parentDiv.removeChild(remDiv);
	},

	htmlentities: function (string, quote_style) {
	    var histogram = {}, symbol = '', tmp_str = '', entity = '';
	    tmp_str = string.toString();
	    
	    if (false === (histogram = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
	        return false;
	    }
	    
	    for (symbol in histogram) {
	        entity = histogram[symbol];
	        tmp_str = tmp_str.split(symbol).join(entity);
	    }
	    
	    return tmp_str;
	},
	
	html_entity_decode: function ( string, quote_style ) {
	    var histogram = {}, symbol = '', tmp_str = '', entity = '';
	    tmp_str = string.toString();
	    
	    if (false === (histogram = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
	        return false;
	    }
	 
	    // &amp; must be the last character when decoding!
	    delete(histogram['&']);
	    histogram['&'] = '&amp;';
	 
	    for (symbol in histogram) {
	        entity = histogram[symbol];
	        tmp_str = tmp_str.split(entity).join(symbol);
	    }
	    
	    return tmp_str;
	},
	
	in_array: function (needle, haystack, argStrict) {
	    // Checks if the given value exists in the array  
	    // 
	    // version: 911.718
	    // discuss at: http://phpjs.org/functions/in_array    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: vlado houba
	    // +   input by: Billy
	    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // *     example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']);    // *     returns 1: true
	    // *     example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
	    // *     returns 2: false
	    // *     example 3: in_array(1, ['1', '2', '3']);
	    // *     returns 3: true    // *     example 3: in_array(1, ['1', '2', '3'], false);
	    // *     returns 3: true
	    // *     example 4: in_array(1, ['1', '2', '3'], true);
	    // *     returns 4: false
	    var key = '', strict = !!argStrict; 
	    if (strict) {
	        for (key in haystack) {
	            if (haystack[key] === needle) { return true; }
	        }
	    } else {
	        for (key in haystack) {
	            if (haystack[key] == needle) { return true; }
	        }
	    }
	    return false;
	},
	
	serialize: function (mixed_value) {
	    // Returns a string representation of variable (which can later be unserialized)  
	    // 
	    // version: 910.813
	    // discuss at: http://phpjs.org/functions/serialize
	    // +   original by: Arpad Ray (mailto:arpad@php.net)
	    // +   improved by: Dino
	    // +   bugfixed by: Andrej Pavlovic
	    // +   bugfixed by: Garagoth
	    // +      input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html)
	    // +   bugfixed by: Russell Walker (http://www.nbill.co.uk/)
	    // +   bugfixed by: Jamie Beck (http://www.terabit.ca/)
	    // +      input by: Martin (http://www.erlenwiese.de/)
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // -    depends on: utf8_encode
	    // %          note: We feel the main purpose of this function should be to ease the transport of data between php & js
	    // %          note: Aiming for PHP-compatibility, we have to translate objects to arrays
	    // *     example 1: serialize(['Kevin', 'van', 'Zonneveld']);
	    // *     returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'
	    // *     example 2: serialize({firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'});
	    // *     returns 2: 'a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}'
	    var _getType = function (inp) {
	        var type = typeof inp, match;
	        var key;
	        if (type == 'object' && !inp) {
	            return 'null';
	        }
	        if (type == "object") {
	            if (!inp.constructor) {
	                return 'object';
	            }
	            var cons = inp.constructor.toString();
	            match = cons.match(/(\w+)\(/);
	            if (match) {
	                cons = match[1].toLowerCase();
	            }
	            var types = ["boolean", "number", "string", "array"];
	            for (key in types) {
	                if (cons == types[key]) {
	                    type = types[key];
	                    break;
	                }
	            }
	        }
	        return type;
	    };
	    var type = _getType(mixed_value);
	    var val, ktype = '';
	    
	    switch (type) {
	        case "function": 
	            val = ""; 
	            break;
	        case "boolean":
	            val = "b:" + (mixed_value ? "1" : "0");
	            break;
	        case "number":
	            val = (Math.round(mixed_value) == mixed_value ? "i" : "d") + ":" + mixed_value;
	            break;
	        case "string":
	            mixed_value = this.utf8_encode(mixed_value);
	            val = "s:" + encodeURIComponent(mixed_value).replace(/%../g, 'x').length + ":\"" + mixed_value + "\"";
	            break;
	        case "array":
	        case "object":
	            val = "a";
	            /*
	            if (type == "object") {
	                var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
	                if (objname == undefined) {
	                    return;
	                }
	                objname[1] = this.serialize(objname[1]);
	                val = "O" + objname[1].substring(1, objname[1].length - 1);
	            }
	            */
	            var count = 0;
	            var vals = "";
	            var okey;
	            var key;
	            for (key in mixed_value) {
	                ktype = _getType(mixed_value[key]);
	                if (ktype == "function") { 
	                    continue; 
	                }
	                
	                okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
	                vals += this.serialize(okey) +
	                        this.serialize(mixed_value[key]);
	                count++;
	            }
	            val += ":" + count + ":{" + vals + "}";
	            break;
	        case "undefined": // Fall-through
	        default: // if the JS object has a property which contains a null value, the string cannot be unserialized by PHP
	            val = "N";
	            break;
	    }
	    if (type != "object" && type != "array") {
	        val += ";";
	    }
	    return val;
	},
		
	str_pad:function (input, pad_length, pad_string, pad_type) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // + namespaced by: Michael White (http://getsprink.com)
	    // +      input by: Marco van Oort
	    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // *     example 1: str_pad('Kevin van Zonneveld', 30, '-=', 'STR_PAD_LEFT');
	    // *     returns 1: '-=-=-=-=-=-Kevin van Zonneveld'
	    // *     example 2: str_pad('Kevin van Zonneveld', 30, '-', 'STR_PAD_BOTH');
	    // *     returns 2: '------Kevin van Zonneveld-----'

	    var half = '', pad_to_go;

	    var str_pad_repeater = function (s, len) {
	        var collect = '', i;

	        while (collect.length < len) {collect += s;}
	        collect = collect.substr(0,len);

	        return collect;
	    };

	    input += '';
	    pad_string = pad_string !== undefined ? pad_string : ' ';
	    
	    if (pad_type != 'STR_PAD_LEFT' && pad_type != 'STR_PAD_RIGHT' && pad_type != 'STR_PAD_BOTH') { pad_type = 'STR_PAD_RIGHT'; }
	    if ((pad_to_go = pad_length - input.length) > 0) {
	        if (pad_type == 'STR_PAD_LEFT') { input = str_pad_repeater(pad_string, pad_to_go) + input; }
	        else if (pad_type == 'STR_PAD_RIGHT') { input = input + str_pad_repeater(pad_string, pad_to_go); }
	        else if (pad_type == 'STR_PAD_BOTH') {
	            half = str_pad_repeater(pad_string, Math.ceil(pad_to_go/2));
	            input = half + input + half;
	            input = input.substr(0, pad_length);
	        }
	    }

	    return input;
	},
	
	unserialize: function (data) {
	    // Takes a string representation of variable and recreates it  
	    // 
	    // version: 911.815
	    // discuss at: http://phpjs.org/functions/unserialize
	    // +     original by: Arpad Ray (mailto:arpad@php.net)
	    // +     improved by: Pedro Tainha (http://www.pedrotainha.com)
	    // +     bugfixed by: dptr1988
	    // +      revised by: d3x
	    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +        input by: Brett Zamir (http://brett-zamir.me)
	    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +     improved by: Chris
	    // +     improved by: James
	    // +        input by: Martin (http://www.erlenwiese.de/)
	    // +     bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +     improved by: Le Torbi
	    // +     input by: kilops
	    // +     bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // -      depends on: utf8_decode
	    // %            note: We feel the main purpose of this function should be to ease the transport of data between php & js
	    // %            note: Aiming for PHP-compatibility, we have to translate objects to arrays
	    // *       example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
	    // *       returns 1: ['Kevin', 'van', 'Zonneveld']
	    // *       example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
	    // *       returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
	    var that = this;
	    var utf8Overhead = function(chr) {
	        // http://phpjs.org/functions/unserialize:571#comment_95906
	        var code = chr.charCodeAt(0);
	        if (code < 0x0080) {
	            return 0;
	        }
	        if (code < 0x0800) {
	             return 1;
	        }
	        return 2;
	    };

	    var error = function (type, msg, filename, line) { throw new that.window[type](msg, filename, line);};
	    var read_until = function (data, offset, stopchr){
	        var buf = [];
	        var chr = data.slice(offset, offset + 1);
	        var i = 2;
	        while (chr != stopchr) {
	            if ((i+offset) > data.length) {
	                error('Error', 'Invalid');
	            }
	            buf.push(chr);
	            chr = data.slice(offset + (i - 1),offset + i);
	            i += 1;
	        }
	        return [buf.length, buf.join('')];
	    };
	    var read_chrs = function (data, offset, length){
	        var buf;

	        buf = [];
	        for (var i = 0;i < length;i++){
	            var chr = data.slice(offset + (i - 1),offset + i);
	            buf.push(chr);
	            length -= utf8Overhead(chr); 
	        }
	        return [buf.length, buf.join('')];
	    };
	    var _unserialize = function (data, offset){
	        var readdata;
	        var readData;
	        var chrs = 0;
	        var ccount;
	        var stringlength;
	        var keyandchrs;
	        var keys;

	        if (!offset) {offset = 0;}
	        var dtype = (data.slice(offset, offset + 1)).toLowerCase();

	        var dataoffset = offset + 2;
	        var typeconvert = function(x) {return x;};

	        switch (dtype){
	            case 'i':
	                typeconvert = function (x) {return parseInt(x, 10);};
	                readData = read_until(data, dataoffset, ';');
	                chrs = readData[0];
	                readdata = readData[1];
	                dataoffset += chrs + 1;
	            break;
	            case 'b':
	                typeconvert = function (x) {return parseInt(x, 10) !== 0;};
	                readData = read_until(data, dataoffset, ';');
	                chrs = readData[0];
	                readdata = readData[1];
	                dataoffset += chrs + 1;
	            break;
	            case 'd':
	                typeconvert = function (x) {return parseFloat(x);};
	                readData = read_until(data, dataoffset, ';');
	                chrs = readData[0];
	                readdata = readData[1];
	                dataoffset += chrs + 1;
	            break;
	            case 'n':
	                readdata = null;
	            break;
	            case 's':
	                ccount = read_until(data, dataoffset, ':');
	                chrs = ccount[0];
	                stringlength = ccount[1];
	                dataoffset += chrs + 2;

	                readData = read_chrs(data, dataoffset+1, parseInt(stringlength, 10));
	                chrs = readData[0];
	                readdata = readData[1];
	                dataoffset += chrs + 2;
	                if (chrs != parseInt(stringlength, 10) && chrs != readdata.length){
	                    error('SyntaxError', 'String length mismatch');
	                }

	                // Length was calculated on an utf-8 encoded string
	                // so wait with decoding
	                readdata = that.utf8_decode(readdata);
	            break;
	            case 'a':
	                readdata = {};

	                keyandchrs = read_until(data, dataoffset, ':');
	                chrs = keyandchrs[0];
	                keys = keyandchrs[1];
	                dataoffset += chrs + 2;

	                for (var i = 0; i < parseInt(keys, 10); i++){
	                    var kprops = _unserialize(data, dataoffset);
	                    var kchrs = kprops[1];
	                    var key = kprops[2];
	                    dataoffset += kchrs;

	                    var vprops = _unserialize(data, dataoffset);
	                    var vchrs = vprops[1];
	                    var value = vprops[2];
	                    dataoffset += vchrs;

	                    readdata[key] = value;
	                }

	                dataoffset += 1;
	            break;
	            default:
	                error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
	            break;
	        }
	        return [dtype, dataoffset - offset, typeconvert(readdata)];
	    };
	    
	    return _unserialize((data+''), 0)[2];
	},
	
	utf8_encode: function ( argString ) {
	    // Encodes an ISO-8859-1 string to UTF-8  
	    // 
	    // version: 909.322
	    // discuss at: http://phpjs.org/functions/utf8_encode
	    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: sowberry
	    // +    tweaked by: Jack
	    // +   bugfixed by: Onno Marsman
	    // +   improved by: Yves Sucaet
	    // +   bugfixed by: Onno Marsman
	    // +   bugfixed by: Ulrich
	    // *     example 1: utf8_encode('Kevin van Zonneveld');
	    // *     returns 1: 'Kevin van Zonneveld'
	    var string = (argString+''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");

	    var utftext = "";
	    var start, end;
	    var stringl = 0;

	    start = end = 0;
	    stringl = string.length;
	    for (var n = 0; n < stringl; n++) {
	        var c1 = string.charCodeAt(n);
	        var enc = null;

	        if (c1 < 128) {
	            end++;
	        } else if (c1 > 127 && c1 < 2048) {
	            enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
	        } else {
	            enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
	        }
	        if (enc !== null) {
	            if (end > start) {
	                utftext += string.substring(start, end);
	            }
	            utftext += enc;
	            start = end = n+1;
	        }
	    }

	    if (end > start) {
	        utftext += string.substring(start, string.length);
	    }

	    return utftext;
	},

	utf8_decode: function ( str_data ) {
	    // Converts a UTF-8 encoded string to ISO-8859-1  
	    // 
	    // version: 909.322
	    // discuss at: http://phpjs.org/functions/utf8_decode
	    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
	    // +      input by: Aman Gupta
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Norman "zEh" Fuchs
	    // +   bugfixed by: hitwork
	    // +   bugfixed by: Onno Marsman
	    // +      input by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // *     example 1: utf8_decode('Kevin van Zonneveld');
	    // *     returns 1: 'Kevin van Zonneveld'
	    var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;
	    
	    str_data += '';
	    
	    while ( i < str_data.length ) {
	        c1 = str_data.charCodeAt(i);
	        if (c1 < 128) {
	            tmp_arr[ac++] = String.fromCharCode(c1);
	            i++;
	        } else if ((c1 > 191) && (c1 < 224)) {
	            c2 = str_data.charCodeAt(i+1);
	            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
	            i += 2;
	        } else {
	            c2 = str_data.charCodeAt(i+1);
	            c3 = str_data.charCodeAt(i+2);
	            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
	            i += 3;
	        }
	    }

	    return tmp_arr.join('');
	},

	
	get_html_translation_table: function (table, quote_style) {
	    var entities = {}, histogram = {}, decimal = 0, symbol = '';
	    var constMappingTable = {}, constMappingQuoteStyle = {};
	    var useTable = {}, useQuoteStyle = {};
	    
	    useTable      = (table ? table.toUpperCase() : 'HTML_SPECIALCHARS');
	    useQuoteStyle = (quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT');
	    
	    // Translate arguments
	    constMappingTable[0]      = 'HTML_SPECIALCHARS';
	    constMappingTable[1]      = 'HTML_ENTITIES';
	    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
	    constMappingQuoteStyle[2] = 'ENT_COMPAT';
	    constMappingQuoteStyle[3] = 'ENT_QUOTES';
	    
	    // Map numbers to strings for compatibilty with PHP constants
	    if (!isNaN(useTable)) {
	        useTable = constMappingTable[useTable];
	    }
	    if (!isNaN(useQuoteStyle)) {
	        useQuoteStyle = constMappingQuoteStyle[useQuoteStyle];
	    }
	    
	    if (useQuoteStyle != 'ENT_NOQUOTES') {
	        entities['34'] = '&quot;';
	    }
	 
	    if (useQuoteStyle == 'ENT_QUOTES') {
	        entities['39'] = '&#039;';
	    }
	 
	    if (useTable == 'HTML_SPECIALCHARS') {
	        // ascii decimals for better compatibility
	        entities['38'] = '&amp;';
	        entities['60'] = '&lt;';
	        entities['62'] = '&gt;';
	    } else if (useTable == 'HTML_ENTITIES') {
	        // ascii decimals for better compatibility
	      entities['38']  = '&amp;';
	      entities['60']  = '&lt;';
	      entities['62']  = '&gt;';
	      entities['160'] = '&nbsp;';
	      entities['161'] = '&iexcl;';
	      entities['162'] = '&cent;';
	      entities['163'] = '&pound;';
	      entities['164'] = '&curren;';
	      entities['165'] = '&yen;';
	      entities['166'] = '&brvbar;';
	      entities['167'] = '&sect;';
	      entities['168'] = '&uml;';
	      entities['169'] = '&copy;';
	      entities['170'] = '&ordf;';
	      entities['171'] = '&laquo;';
	      entities['172'] = '&not;';
	      entities['173'] = '&shy;';
	      entities['174'] = '&reg;';
	      entities['175'] = '&macr;';
	      entities['176'] = '&deg;';
	      entities['177'] = '&plusmn;';
	      entities['178'] = '&sup2;';
	      entities['179'] = '&sup3;';
	      entities['180'] = '&acute;';
	      entities['181'] = '&micro;';
	      entities['182'] = '&para;';
	      entities['183'] = '&middot;';
	      entities['184'] = '&cedil;';
	      entities['185'] = '&sup1;';
	      entities['186'] = '&ordm;';
	      entities['187'] = '&raquo;';
	      entities['188'] = '&frac14;';
	      entities['189'] = '&frac12;';
	      entities['190'] = '&frac34;';
	      entities['191'] = '&iquest;';
	      entities['192'] = '&Agrave;';
	      entities['193'] = '&Aacute;';
	      entities['194'] = '&Acirc;';
	      entities['195'] = '&Atilde;';
	      entities['196'] = '&Auml;';
	      entities['197'] = '&Aring;';
	      entities['198'] = '&AElig;';
	      entities['199'] = '&Ccedil;';
	      entities['200'] = '&Egrave;';
	      entities['201'] = '&Eacute;';
	      entities['202'] = '&Ecirc;';
	      entities['203'] = '&Euml;';
	      entities['204'] = '&Igrave;';
	      entities['205'] = '&Iacute;';
	      entities['206'] = '&Icirc;';
	      entities['207'] = '&Iuml;';
	      entities['208'] = '&ETH;';
	      entities['209'] = '&Ntilde;';
	      entities['210'] = '&Ograve;';
	      entities['211'] = '&Oacute;';
	      entities['212'] = '&Ocirc;';
	      entities['213'] = '&Otilde;';
	      entities['214'] = '&Ouml;';
	      entities['215'] = '&times;';
	      entities['216'] = '&Oslash;';
	      entities['217'] = '&Ugrave;';
	      entities['218'] = '&Uacute;';
	      entities['219'] = '&Ucirc;';
	      entities['220'] = '&Uuml;';
	      entities['221'] = '&Yacute;';
	      entities['222'] = '&THORN;';
	      entities['223'] = '&szlig;';
	      entities['224'] = '&agrave;';
	      entities['225'] = '&aacute;';
	      entities['226'] = '&acirc;';
	      entities['227'] = '&atilde;';
	      entities['228'] = '&auml;';
	      entities['229'] = '&aring;';
	      entities['230'] = '&aelig;';
	      entities['231'] = '&ccedil;';
	      entities['232'] = '&egrave;';
	      entities['233'] = '&eacute;';
	      entities['234'] = '&ecirc;';
	      entities['235'] = '&euml;';
	      entities['236'] = '&igrave;';
	      entities['237'] = '&iacute;';
	      entities['238'] = '&icirc;';
	      entities['239'] = '&iuml;';
	      entities['240'] = '&eth;';
	      entities['241'] = '&ntilde;';
	      entities['242'] = '&ograve;';
	      entities['243'] = '&oacute;';
	      entities['244'] = '&ocirc;';
	      entities['245'] = '&otilde;';
	      entities['246'] = '&ouml;';
	      entities['247'] = '&divide;';
	      entities['248'] = '&oslash;';
	      entities['249'] = '&ugrave;';
	      entities['250'] = '&uacute;';
	      entities['251'] = '&ucirc;';
	      entities['252'] = '&uuml;';
	      entities['253'] = '&yacute;';
	      entities['254'] = '&thorn;';
	      entities['255'] = '&yuml;';
	    } else {
	        throw Error("Table: "+useTable+' not supported');
	        return false;
	    }
	    
	    // ascii decimals to real symbols
	    for (decimal in entities) {
	        symbol = String.fromCharCode(decimal)
	        histogram[symbol] = entities[decimal];
	    }
	    
	    return histogram;
	}
}
