










/**
 * A class to parse color values
 * @author Stoyan Stefanov <sstoo@gmail.com>
 * @link   http://www.phpied.com/rgb-color-parser-in-javascript/
 * @license Use it if you like it
 */
function RGBColor(color_string)
{
    this.ok = false;

    // strip any leading #
    if (color_string.charAt(0) == '#') { // remove # if any
        color_string = color_string.substr(1,6);
    }

    color_string = color_string.replace(/ /g,'');
    color_string = color_string.toLowerCase();

    // before getting into regexps, try simple matches
    // and overwrite the input
    var simple_colors = {
        aliceblue: 'f0f8ff',
        antiquewhite: 'faebd7',
        aqua: '00ffff',
        aquamarine: '7fffd4',
        azure: 'f0ffff',
        beige: 'f5f5dc',
        bisque: 'ffe4c4',
        black: '000000',
        blanchedalmond: 'ffebcd',
        blue: '0000ff',
        blueviolet: '8a2be2',
        brown: 'a52a2a',
        burlywood: 'deb887',
        cadetblue: '5f9ea0',
        chartreuse: '7fff00',
        chocolate: 'd2691e',
        coral: 'ff7f50',
        cornflowerblue: '6495ed',
        cornsilk: 'fff8dc',
        crimson: 'dc143c',
        cyan: '00ffff',
        darkblue: '00008b',
        darkcyan: '008b8b',
        darkgoldenrod: 'b8860b',
        darkgray: 'a9a9a9',
        darkgreen: '006400',
        darkkhaki: 'bdb76b',
        darkmagenta: '8b008b',
        darkolivegreen: '556b2f',
        darkorange: 'ff8c00',
        darkorchid: '9932cc',
        darkred: '8b0000',
        darksalmon: 'e9967a',
        darkseagreen: '8fbc8f',
        darkslateblue: '483d8b',
        darkslategray: '2f4f4f',
        darkturquoise: '00ced1',
        darkviolet: '9400d3',
        deeppink: 'ff1493',
        deepskyblue: '00bfff',
        dimgray: '696969',
        dodgerblue: '1e90ff',
        feldspar: 'd19275',
        firebrick: 'b22222',
        floralwhite: 'fffaf0',
        forestgreen: '228b22',
        fuchsia: 'ff00ff',
        gainsboro: 'dcdcdc',
        ghostwhite: 'f8f8ff',
        gold: 'ffd700',
        goldenrod: 'daa520',
        gray: '808080',
        green: '008000',
        greenyellow: 'adff2f',
        honeydew: 'f0fff0',
        hotpink: 'ff69b4',
        indianred : 'cd5c5c',
        indigo : '4b0082',
        ivory: 'fffff0',
        khaki: 'f0e68c',
        lavender: 'e6e6fa',
        lavenderblush: 'fff0f5',
        lawngreen: '7cfc00',
        lemonchiffon: 'fffacd',
        lightblue: 'add8e6',
        lightcoral: 'f08080',
        lightcyan: 'e0ffff',
        lightgoldenrodyellow: 'fafad2',
        lightgrey: 'd3d3d3',
        lightgreen: '90ee90',
        lightpink: 'ffb6c1',
        lightsalmon: 'ffa07a',
        lightseagreen: '20b2aa',
        lightskyblue: '87cefa',
        lightslateblue: '8470ff',
        lightslategray: '778899',
        lightsteelblue: 'b0c4de',
        lightyellow: 'ffffe0',
        lime: '00ff00',
        limegreen: '32cd32',
        linen: 'faf0e6',
        magenta: 'ff00ff',
        maroon: '800000',
        mediumaquamarine: '66cdaa',
        mediumblue: '0000cd',
        mediumorchid: 'ba55d3',
        mediumpurple: '9370d8',
        mediumseagreen: '3cb371',
        mediumslateblue: '7b68ee',
        mediumspringgreen: '00fa9a',
        mediumturquoise: '48d1cc',
        mediumvioletred: 'c71585',
        midnightblue: '191970',
        mintcream: 'f5fffa',
        mistyrose: 'ffe4e1',
        moccasin: 'ffe4b5',
        navajowhite: 'ffdead',
        navy: '000080',
        oldlace: 'fdf5e6',
        olive: '808000',
        olivedrab: '6b8e23',
        orange: 'ffa500',
        orangered: 'ff4500',
        orchid: 'da70d6',
        palegoldenrod: 'eee8aa',
        palegreen: '98fb98',
        paleturquoise: 'afeeee',
        palevioletred: 'd87093',
        papayawhip: 'ffefd5',
        peachpuff: 'ffdab9',
        peru: 'cd853f',
        pink: 'ffc0cb',
        plum: 'dda0dd',
        powderblue: 'b0e0e6',
        purple: '800080',
        red: 'ff0000',
        rosybrown: 'bc8f8f',
        royalblue: '4169e1',
        saddlebrown: '8b4513',
        salmon: 'fa8072',
        sandybrown: 'f4a460',
        seagreen: '2e8b57',
        seashell: 'fff5ee',
        sienna: 'a0522d',
        silver: 'c0c0c0',
        skyblue: '87ceeb',
        slateblue: '6a5acd',
        slategray: '708090',
        snow: 'fffafa',
        springgreen: '00ff7f',
        steelblue: '4682b4',
        tan: 'd2b48c',
        teal: '008080',
        thistle: 'd8bfd8',
        tomato: 'ff6347',
        turquoise: '40e0d0',
        violet: 'ee82ee',
        violetred: 'd02090',
        wheat: 'f5deb3',
        white: 'ffffff',
        whitesmoke: 'f5f5f5',
        yellow: 'ffff00',
        yellowgreen: '9acd32'
    };
    for (var key in simple_colors) {
        if (color_string == key) {
            color_string = simple_colors[key];
        }
    }
    // emd of simple type-in colors

    // array of color definition objects
    var color_defs = [
        {
            re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
            example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
            process: function (bits){
                return [
                    parseInt(bits[1]),
                    parseInt(bits[2]),
                    parseInt(bits[3])
                ];
            }
        },
        {
            re: /^(\w{2})(\w{2})(\w{2})$/,
            example: ['#00ff00', '336699'],
            process: function (bits){
                return [
                    parseInt(bits[1], 16),
                    parseInt(bits[2], 16),
                    parseInt(bits[3], 16)
                ];
            }
        },
        {
            re: /^(\w{1})(\w{1})(\w{1})$/,
            example: ['#fb0', 'f0f'],
            process: function (bits){
                return [
                    parseInt(bits[1] + bits[1], 16),
                    parseInt(bits[2] + bits[2], 16),
                    parseInt(bits[3] + bits[3], 16)
                ];
            }
        }
    ];

    // search through the definitions to find a match
    for (var i = 0; i < color_defs.length; i++) {
        var re = color_defs[i].re;
        var processor = color_defs[i].process;
        var bits = re.exec(color_string);
        if (bits) {
            channels = processor(bits);
            this.r = channels[0];
            this.g = channels[1];
            this.b = channels[2];
            this.ok = true;
        }

    }

    // validate/cleanup values
    this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
    this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
    this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);

    // some getters
    this.toRGB = function () {
        return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
    }
    this.toHex = function () {
        var r = this.r.toString(16);
        var g = this.g.toString(16);
        var b = this.b.toString(16);
        if (r.length == 1) r = '0' + r;
        if (g.length == 1) g = '0' + g;
        if (b.length == 1) b = '0' + b;
        return '#' + r + g + b;
    }

    // help
    this.getHelpXML = function () {

        var examples = new Array();
        // add regexps
        for (var i = 0; i < color_defs.length; i++) {
            var example = color_defs[i].example;
            for (var j = 0; j < example.length; j++) {
                examples[examples.length] = example[j];
            }
        }
        // add type-in colors
        for (var sc in simple_colors) {
            examples[examples.length] = sc;
        }

        var xml = document.createElement('ul');
        xml.setAttribute('id', 'rgbcolor-examples');
        for (var i = 0; i < examples.length; i++) {
            try {
                var list_item = document.createElement('li');
                var list_color = new RGBColor(examples[i]);
                var example_div = document.createElement('div');
                example_div.style.cssText =
                        'margin: 3px; '
                        + 'border: 1px solid black; '
                        + 'background:' + list_color.toHex() + '; '
                        + 'color:' + list_color.toHex()
                ;
                example_div.appendChild(document.createTextNode('test'));
                var list_item_value = document.createTextNode(
                    ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
                );
                list_item.appendChild(example_div);
                list_item.appendChild(list_item_value);
                xml.appendChild(list_item);

            } catch(e){}
        }
        return xml;

    }

}



function PnyxeCommon() {
	this.getTopMostWindowLocationHref = function() {
		try {
			var currWindow = window;
			var currWindowLocationHref = currWindow.location.href;
			var parentWindow = currWindow.parent;

			try {
				// Maximum of 10 parent windows to avoid endless loop
				for (i = 0; i < 10 && parentWindow != currWindow; ++i) {
					// Firefox will throw an exception here if parent window is of a different domain
					// Chrome just denies access to it
					if (typeof(parentWindow.location.href) == "undefined") {
						break;
					}
					currWindow = parentWindow;
					currWindowLocationHref = currWindow.location.href; // IE will throw an exception here if parent window is of a different domain
					parentWindow = currWindow.parent;
				}
			} catch (exception) {
				// Ignore Firefox and IE exceptions
			}
			
			return currWindowLocationHref;
		
		} catch (exception) {
			this.logException("PnyxeCommon.getTopMostWindowLocationHref", exception);
			throw exception;
		}
	}
	
	this.getArticleUrlDetails = function(implicitArticleUrl) {
		try {
			// Extracting and removing postKey parameter from implicitArticleUrl
			var extractResult = this.extractQueryStringParameter(implicitArticleUrl, "zpbw_postKey");
			var webWidgetPostKey = extractResult.paramValue;
			implicitArticleUrl = extractResult.url;

			// Backwards compatibility
			if (webWidgetPostKey == null || webWidgetPostKey.length == 0) {
				extractResult = this.extractQueryStringParameter(implicitArticleUrl, "pnyxePostKey");
				webWidgetPostKey = extractResult.paramValue;
				implicitArticleUrl = extractResult.url;
			}
			
			// Extracting and removing userKey parameter from implicitArticleUrl
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "zpbw_userKey");
			var webWidgetUserKey = extractResult.paramValue;
			implicitArticleUrl = extractResult.url;

			// Backwards compatibility
			if (webWidgetUserKey == null || webWidgetUserKey.length == 0) {
				extractResult = this.extractQueryStringParameter(implicitArticleUrl, "pnyxeUserKey");
				webWidgetUserKey = extractResult.paramValue;
				implicitArticleUrl = extractResult.url;
			}
			
			// Extracting and removing GWT code server parameter from implicitArticleUrl
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "gwt.codesvr");
			var gwtCodeServer = extractResult.paramValue;
			implicitArticleUrl = extractResult.url;
			
			// Removing Facebook ref(ferrer)=nf(newsfeed) parameter from implicitArticleUrl
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "ref");
			if (typeof(extractResult.paramValue) != "undefined" && extractResult.paramValue=="nf") {
				implicitArticleUrl = extractResult.url;
			}
			
			// Removing Google AdWords link url tagging parameter (gclid) from implicitArticleUrl
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "gclid");
			implicitArticleUrl = extractResult.url;
			
			// Removing possible rss=true parameter from implicitArticleUrl
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "rss");
			if (typeof(extractResult.paramValue) != "undefined" && extractResult.paramValue=="true") {
				implicitArticleUrl = extractResult.url;
			}
			
			// Presentational Widgets - extracting webWidgetClientKey, menuOption, action, postKey, resetPassword, userKey, verificationCode
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "webWidgetClientKey");
			var presentationalWebWidgetClientKey = extractResult.paramValue;
			
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "menuOption");
			var presentationalMenuOption = extractResult.paramValue;
			
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "action");
			var presentationalAction = extractResult.paramValue;
			
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "postKey");
			var presentationalPostKey = extractResult.paramValue;
			
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "resetPassword");
			var presentationalResetPassword = extractResult.paramValue;
			
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "userKey");
			var presentationalUserKey = extractResult.paramValue;
			
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "verificationCode");
			var presentationalVerificationCode = extractResult.paramValue;
			
			// Extracting and removing TalkAhead's previewComment parameter from implicitArticleUrl
			var extractResult = this.extractQueryStringParameter(implicitArticleUrl, "previewComment");
			var previewComment;
			if (typeof(extractResult.paramValue) != "undefined") {
				previewComment = extractResult.paramValue;
				implicitArticleUrl = extractResult.url;
			}
			
			// Removing Google Analytics parameters (utm_*) from implicitArticleUrl - used for JangoMail integration (https://www.jangomail.com/APPLICATION2/options/GA.asp)
			extractResult = this.extractQueryStringParameter(implicitArticleUrl, "utm_source");
			extractResult = this.extractQueryStringParameter(extractResult.url, "utm_medium");
			extractResult = this.extractQueryStringParameter(extractResult.url, "utm_content");
			extractResult = this.extractQueryStringParameter(extractResult.url, "utm_campaign");
			implicitArticleUrl = extractResult.url;
			
			var result = new Object();
			result.implicitArticleUrl = implicitArticleUrl;
			result.webWidgetPostKey = webWidgetPostKey;
			result.webWidgetUserKey = webWidgetUserKey;
			result.gwtCodeServer = gwtCodeServer;
			result.presentationalWebWidgetClientKey = presentationalWebWidgetClientKey;
			result.presentationalMenuOption = presentationalMenuOption;
			result.presentationalAction = presentationalAction;
			result.presentationalPostKey = presentationalPostKey;
			result.presentationalResetPassword = presentationalResetPassword;
			result.presentationalUserKey = presentationalUserKey;
			result.presentationalVerificationCode = presentationalVerificationCode;
			result.previewComment = previewComment;
			return result;

		} catch (exception) {
			this.logException("PnyxeCommon.getArticleUrlDetails", exception);
			throw exception;
		}
	}

	// Backwards compatibility
	this.getVariablesSingleValue = function(/* Any number of variable names */) {
		try {
			for (var i = 0; i < arguments.length; ++i) {
				var varName = arguments[i];
				if (eval("typeof(" + varName + ")") != "undefined") {
					return eval(varName);
				}
			}
			
			return null;

		} catch (exception) {
			this.logException("PnyxeCommon.getVariablesSingleValue", exception);
			throw exception;
		}
	}

	this.extractQueryStringParameter = function(url, paramName) {
		try {
			var paramValue;
			
			// Search where the parameter starts
			var paramStartIndex = url.indexOf("?" + paramName + "=");
			if (paramStartIndex == -1) {
				paramStartIndex = url.indexOf("&" + paramName + "=");
			}
			
			if (paramStartIndex != -1) {
				// Search where the parameter ends
				var paramEndIndex = url.indexOf("&", paramStartIndex + 1);
				if (paramEndIndex == -1) {
					paramEndIndex = url.indexOf("#", paramStartIndex + 1);
				}
				if (paramEndIndex == -1) {
					paramEndIndex = url.length;
				}
				
				// Extract the parameter value
				paramValue = url.substring(paramStartIndex + 1 + paramName.length + 1, paramEndIndex);
				
				var separators = url.charAt(paramStartIndex) + url.charAt(paramEndIndex);
				var newSeparator = "";
				if (separators == "?&") {
					newSeparator = "?";
				} else if (separators == "?#") {
					newSeparator = "#";
				} else if (separators == "&&") {
					newSeparator = "&";
				} else if (separators == "&#") {
					newSeparator = "#";
				} else if (separators == "?") {
					newSeparator = "";
				} else if (separators == "&") {
					newSeparator = "";
				}
				url = url.substring(0, paramStartIndex) + newSeparator + url.substring(paramEndIndex + 1);
			}
			
			var result = new Object();
			result.url = url;
			result.paramValue = paramValue;
			return result;
			
		} catch (exception) {
			this.logException("PnyxeCommon.extractQueryStringParameter", exception);
			throw exception;
		}
	}
	
	this.removeExistingElements = function(elementId, elementsNoToRemove) {
		try {
			var existingElement = document.getElementById(elementId);
			while (existingElement != null && (elementsNoToRemove == null || elementsNoToRemove > 0)) {
				existingElement.parentNode.removeChild(existingElement);
				existingElement = document.getElementById(elementId);
				
				if (elementsNoToRemove != null) {
					--elementsNoToRemove;
				}
			}
		
		} catch (exception) {
			this.logException("PnyxeCommon.removeExistingElements", exception);
		}
	}
	
	this.removeExistingElementsExceptLast = function(elementId) {
		try {
			var scriptElements = document.getElementsByTagName("script");
			var pnyxeScriptElementsNo = 0;
			for (var i = 0; i < scriptElements.length; ++i) {
				var currScriptElement = scriptElements[i];
				if (currScriptElement.getAttribute("id") == elementId) {
					++pnyxeScriptElementsNo;
				}
			}
			
			this.removeExistingElements(elementId, pnyxeScriptElementsNo - 1);
		
		} catch (exception) {
			this.logException("PnyxeCommon.removeExistingElementsExceptLast", exception);
		}
	}
	
	this.createFrame = function(frameId, height) {
		try {
			var theFrame = document.createElement("iframe");
			theFrame.setAttribute("id", frameId);
			theFrame.setAttribute("name", frameId);
			theFrame.setAttribute("frameBorder", "0");
			theFrame.setAttribute("marginHeight", "0");
			theFrame.setAttribute("marginWidth", "0");
			theFrame.setAttribute("allowTransparency", "true");
			theFrame.style["backgroundColor"] = "transparent";
			theFrame.style["width"] = "100%";
			theFrame.style["height"] = height;
			theFrame.style["padding"] = "0px";
			theFrame.style["border"] = "0px";
			theFrame.style["margin"] = "0px";

			theFrame.setAttribute("scrolling", "no");
			theFrame.style["overflow"] = "hidden";
			
			return theFrame;
		} catch (exception) {
			this.logException("PnyxeCommon.createFrame", exception);
			throw exception;
		}
	}

	this.createFixedLayoutTable = function(tableId) {
		try {
			var theTable = document.createElement("table");
			theTable.setAttribute("id", tableId);
			theTable.setAttribute("cellPadding", "0");
			theTable.setAttribute("cellSpacing", "0");
			theTable.setAttribute("border", "0");
			theTable.style["tableLayout"] = "fixed";
			theTable.style["width"] = "100%";
			theTable.insertRow(0);
			theTable.rows[0].insertCell(0);
			
			return theTable;
		} catch (exception) {
			this.logException("PnyxeCommon.createFixedLayoutTable", exception);
			throw exception;
		}
	}

	this.getForegroundColor = function(element) {
		try {
			var fgColor = null;
			
			// No need to catch exceptions since all elements have "color" style attribute - it's an inherited attribute
			if (typeof(element.currentStyle) != "undefined") {
				fgColor = element.currentStyle.getAttribute("color"); // IE
			} else {
				fgColor = getComputedStyle(element, null).getPropertyValue("color") // Other browsers
			}
			
			return fgColor;
		} catch (exception) {
			this.logException("PnyxeCommon.getForegroundColor", exception);
			return "black";
		}
	}
	
	this.getBackgroundColor = function(element) {
		try {
			var bgColor = null;
			
			// FF sometimes throws exceptions when trying to retrieve "background-color" style attribute of "HTML" element (non inherited)
			try {
				if (typeof(element.currentStyle) != "undefined") {
					bgColor = element.currentStyle.getAttribute("backgroundColor"); // IE
				} else {
					bgColor = getComputedStyle(element, null).getPropertyValue("background-color") // Other browsers
				}
			} catch (e) {
				bgColor = "transparent";
			}
			
			// rgba - Safari's implicit transparent
			if (bgColor != null && bgColor.length > 0 && bgColor != "transparent" && bgColor != "undefined" && bgColor != "rgba(0, 0, 0, 0)") {
				return bgColor;
			}
			
			var parentElement = element.parentNode;
			if (parentElement != null) {
				return this.getBackgroundColor(parentElement);
			} else {
				return "transparent";
			}
		} catch (exception) {
			this.logException("PnyxeCommon.getBackgroundColor", exception);
			return "transparent";
		}
	}

	this.toHexColor = function(inputColor, defaultColor) {
		var color = new RGBColor(inputColor);
		if (color.ok) {
			return color.toHex();
		} else {
			return defaultColor;
		}
	}

	this.initAutoResizeMechanism = function(widgetFrameId, widgetObjectName, minHeight) {
		if (typeof(window.postMessage) != "undefined" && window.postMessage != null &&
				typeof(window.addEventListener) != "undefined" && window.addEventListener != null) {
			window.addEventListener('message', this.parsePostedMessage, false);
		} else if (typeof(window.postMessage) != "undefined" && window.postMessage != null &&
							 typeof(window.attachEvent) != "undefined" && window.attachEvent != null) {
			// IE8
			window.attachEvent('onmessage', this.parsePostedMessage);
		} else {
			this.scheduleHeightMessageTimer(widgetFrameId, widgetObjectName, minHeight);
		}
	}
	
	this.parsePostedMessage = function(message) {
		if (message.origin.indexOf("pnyxe.co.il") >= 0 && message.data) {
			var parametersArray = message.data.split("&");
			var parametersHash = new Object();
			for (var i=0; i < parametersArray.length; ++i) {
				var parameterArray = parametersArray[i].split("=");
				parametersHash[parameterArray[0]] = parameterArray[1];
			}
			
			if (typeof(parametersHash["widgetFrameId"]) != "undefined" && parametersHash["widgetFrameId"] != null &&
					typeof(parametersHash["height"]) != "undefined" && parametersHash["height"] != null) {
				document.getElementById(parametersHash["widgetFrameId"]).style["height"] = parametersHash["height"] + "px";
			}
		}
	}
	
	this.scheduleHeightMessageTimer = function(widgetFrameId, widgetObjectName, minHeight) {
		setTimeout(widgetObjectName + ".pnyxeCommon.heightMessageTimer(\"" + widgetFrameId + "\", \"" + widgetObjectName + "\", \"" + minHeight + "\")", 400);
	}
	
	this.heightMessageTimer = function(widgetFrameId, widgetObjectName, minHeight) {
		try {
			// Search for a new auto resize frame only if height changed
			var currHeight = document.getElementById(widgetFrameId).style["height"];
			currHeight = currHeight.substring(0, currHeight.length - 2);
			if (!this.isAutoResizeFrameExists(currHeight)) {
				var newHeight = 0;
				var autoResizeFrameFound = false;
				while (!autoResizeFrameFound && newHeight <= 20000) {
					newHeight += 100;
					autoResizeFrameFound = this.isAutoResizeFrameExists(widgetFrameId, newHeight);
				}
				
				if (newHeight < minHeight) {
					newHeight = minHeight;
				}
				
				if (autoResizeFrameFound) {
					document.getElementById(widgetFrameId).style["height"] = newHeight + "px";
				}
			}
			
			this.scheduleHeightMessageTimer(widgetFrameId, widgetObjectName, minHeight);
		} catch (exception) {
			this.logException("PnyxeCommon.heightMessageTimer", exception);
		}
	}
	
	this.isAutoResizeFrameExists = function(widgetFrameId, height) {
		try {
			// IFrame:	Existing			Non-Existing
			//			--------			------------
			// IE6:		Permission denied	undefined
			// IE7:		Object				undefined
			// FF:		Object				Error: Permission denied to get property...
			// Safari:	Object				undefined
			var autoResizeFrame = window.frames[widgetFrameId].frames["autoResizeFrame" + height];
			if (typeof(autoResizeFrame) != "undefined") {
				return true; // For IE7, FF, Safari
			}
		} catch (e) {
			if (this.getExceptionMessage(e) == "Permission denied") {
				return true; // For IE6
			}
		}
		
		return false;
	}
	
	this.getExceptionMessage = function(exception) {
		if (exception.description) {
			// IE throws Error object containing a description
			return exception.description;
		} else {
			return exception;
		}
	}
	
	this.logException = function(functionName, exception) {
		try {
			var exceptionMessage = this.getExceptionMessage(exception);

			var logImage = document.createElement("img");
			logImage.setAttribute("id", "pnyxeExceptionImg");
			logImage.setAttribute("src", "http://www.pnyxe.co.il/JavascriptException?function=" + encodeURIComponent(functionName) + ",exception=" + encodeURIComponent(exceptionMessage) + ",href=" + encodeURIComponent(window.location.href) + ",referrer=" + encodeURIComponent(document.referrer));
			logImage.style["width"] = "0px";
			logImage.style["height"] = "0px";
			logImage.style["padding"] = "0px";
			logImage.style["border"] = "0px";
			logImage.style["margin"] = "0px";
			
			// Adding objects to the body element in IE is allowed only when the script is a direct child of it
			// see http://www.nirmaltv.com/2007/08/08/how-to-fix-internet-explorer-cannot-open-the-internet-site-operation-aborted-error/
			var elementToInsertBefore = document.getElementById("pnyxeDiscussItJs");
			if (elementToInsertBefore == null) {
				elementToInsertBefore = document.getElementById("pnyxeRecentPostsJs");
			}
			if (elementToInsertBefore == null) {
				elementToInsertBefore = document.getElementById("pnyxeForumItJs");
			}
			if (elementToInsertBefore == null) {
				elementToInsertBefore = document.getElementById("pnyxeWebWidgetJs"); // Old version
			}
			elementToInsertBefore.parentNode.insertBefore(logImage, elementToInsertBefore);
			
		} catch (e) {
		}
	}
};


function PnyxeForumIt() {
	this.pnyxeCommon = new PnyxeCommon();
	
	this.init = function(uniqueSuffix) {
		try {
			// Cleaning up existing Pnyxe elements (might be created during a page preview)
			if (typeof(window.isPnyxeForumItCleanupDone) == "undefined") {
				window.isPnyxeForumItCleanupDone = true;
				this.pnyxeCommon.removeExistingElements("pnyxeForumItTable", null);
				this.pnyxeCommon.removeExistingElements("pnyxeExceptionImg", null);
				this.pnyxeCommon.removeExistingElements("pnyxeForumItFrame", null); // Old version
			}

			// Creating a layout fixed table so 100% width will work also in IE (even after setting new height)
			var pnyxeForumItTable = this.pnyxeCommon.createFixedLayoutTable("pnyxeForumItTable");

			if (typeof(uniqueSuffix) == "undefined") {
				uniqueSuffix = ""; // Old version
			}
			
			var pnyxeForumItInitJsId = "pnyxeForumItInitJs" + uniqueSuffix;
			var pnyxeForumItInitJs = document.getElementById(pnyxeForumItInitJsId);
			if (pnyxeForumItInitJs == null) {
				throw "Cannot find pnyxeForumItInitJs";
			}

			// Creating a frame with a unique name so it can be set and resized individually
			var pnyxeForumItFrameId = "pnyxeForumItFrame" + uniqueSuffix;
			var pnyxeForumItFrameHeight = 300;
			var pnyxeForumItFrame = this.pnyxeCommon.createFrame(pnyxeForumItFrameId, pnyxeForumItFrameHeight + "px");
			pnyxeForumItTable.rows[0].cells[0].appendChild(pnyxeForumItFrame);
			pnyxeForumItInitJs.parentNode.insertBefore(pnyxeForumItTable, pnyxeForumItInitJs);

			// Creating IFrame src
			var iFrameSrc = "http://www.pnyxe.co.il/PnyxeForumIt.jsp";

			// webWidgetClientKey
			var webWidgetClientKey = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_clientKey", "zpbw_webWidgetClientKey");
			if (webWidgetClientKey == null || webWidgetClientKey.length == 0) {
				webWidgetClientKey = "PwJ7vexlhYzFXgBlVDxdnA";
			}
			iFrameSrc += "?webWidgetClientKey=" + encodeURIComponent(webWidgetClientKey);
			
			// webWidgetArticleUrl
			var webWidgetArticleUrl = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_articleUrl", "zpbw_webWidgetArticleUrl");
			var isImplicitArticleUrl = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_isImplicitArticleUrl", "zpbw_isImplicitArticleUrl");
			var articleDetails;
			var effectiveArticleUrl;
			
			if (webWidgetArticleUrl == null || webWidgetArticleUrl.length == 0) {
				// No webWidgetArticleUrl
				isImplicitArticleUrl = true;
				articleDetails = this.pnyxeCommon.getArticleUrlDetails(this.pnyxeCommon.getTopMostWindowLocationHref());
				effectiveArticleUrl = articleDetails.implicitArticleUrl;
			
			} else if (isImplicitArticleUrl != null && isImplicitArticleUrl) {
				// webWidgetArticleUrl is explicitly provided but should be considered as implicit due to isImplicitArticleUrl
				// e.g. WidgetBox
				isImplicitArticleUrl = true;
				articleDetails = this.pnyxeCommon.getArticleUrlDetails(webWidgetArticleUrl);
				effectiveArticleUrl = articleDetails.implicitArticleUrl;
			
			} else {
				// webWidgetArticleUrl is explicitly provided
				isImplicitArticleUrl = false;
				articleDetails = this.pnyxeCommon.getArticleUrlDetails(this.pnyxeCommon.getTopMostWindowLocationHref());
				effectiveArticleUrl = webWidgetArticleUrl;
			}
			
			// webWidgetArticleUrl is truncated due to server limitation
			effectiveArticleUrl = effectiveArticleUrl.substring(0, 255);
			iFrameSrc += "&webWidgetArticleUrl=" + encodeURIComponent(effectiveArticleUrl);
			iFrameSrc += "&isImplicitUrl=" + encodeURIComponent(isImplicitArticleUrl);
			
			// webWidgetPostKey
			if (typeof(articleDetails.webWidgetPostKey) != "undefined" && articleDetails.webWidgetPostKey.length > 0) {
				iFrameSrc += "&webWidgetPostKey=" + encodeURIComponent(articleDetails.webWidgetPostKey);

				pnyxeForumItFrameHeight = 500;
				pnyxeForumItFrame.style["height"] = pnyxeForumItFrameHeight + "px";
				setTimeout("document.getElementById('" + pnyxeForumItFrameId + "').scrollIntoView(false)", 1);
			}
			
			// userKey
			if (typeof(articleDetails.webWidgetUserKey) != "undefined" && articleDetails.webWidgetUserKey.length > 0) {
				iFrameSrc += "&action=userDisplay&userKey=" + encodeURIComponent(articleDetails.webWidgetUserKey);

				pnyxeForumItFrameHeight = 800;
				pnyxeForumItFrame.style["height"] = pnyxeForumItFrameHeight + "px";
				setTimeout("document.getElementById('" + pnyxeForumItFrameId + "').scrollIntoView(false)", 1);
			}
			
			// platform (used for demos)
			var platform = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_platform", "zpbw_webWidgetPlatform");
			if (platform != null && platform.length > 0) {
				iFrameSrc += "&platform=" + encodeURIComponent(platform);
			}
			
			// webWidgetSsoUserId
			var webWidgetSsoUserId = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_ssoUserId", "zpbw_webWidgetSsoUserId");
			if (webWidgetSsoUserId != null && webWidgetSsoUserId.length > 0) {
				iFrameSrc += "&webWidgetSsoUserId=" + encodeURIComponent(webWidgetSsoUserId);
			}
			
			// webWidgetSsoUserNickname
			var webWidgetSsoUserNickname = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_ssoUserNickname", "zpbw_webWidgetSsoUserNickname");
			if (webWidgetSsoUserNickname != null && webWidgetSsoUserNickname.length > 0) {
				iFrameSrc += "&webWidgetSsoUserNickname=" + encodeURIComponent(webWidgetSsoUserNickname);
			}
			
			// webWidgetSsoUserEmailAddress
			var webWidgetSsoUserEmailAddress = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_ssoUserEmailAddress", "zpbw_webWidgetSsoUserEmailAddress");
			if (webWidgetSsoUserEmailAddress != null && webWidgetSsoUserEmailAddress.length > 0) {
				iFrameSrc += "&webWidgetSsoUserEmailAddress=" + encodeURIComponent(webWidgetSsoUserEmailAddress);
			}
			
			// webWidgetSsoIsUserEmailAddressVerified
			var webWidgetSsoIsUserEmailAddressVerified = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_ssoIsUserEmailAddressVerified", "zpbw_webWidgetSsoIsUserEmailAddressVerified");
			if (webWidgetSsoIsUserEmailAddressVerified != null && webWidgetSsoIsUserEmailAddressVerified.length > 0) {
				iFrameSrc += "&webWidgetSsoIsUserEmailAddressVerified=" + encodeURIComponent(webWidgetSsoIsUserEmailAddressVerified);
			}
			
			// webWidgetSsoSignature
			var webWidgetSsoSignature = this.pnyxeCommon.getVariablesSingleValue("pnyxeWebWidget_ssoSignature", "zpbw_webWidgetSsoSignature");
			if (webWidgetSsoSignature != null && webWidgetSsoSignature.length > 0) {
				iFrameSrc += "&webWidgetSsoSignature=" + encodeURIComponent(webWidgetSsoSignature);
			}
			
			// Colors
			var fgColor = this.pnyxeCommon.toHexColor(this.pnyxeCommon.getForegroundColor(pnyxeForumItInitJs.parentNode));
			var bgColor = this.pnyxeCommon.toHexColor(this.pnyxeCommon.getBackgroundColor(pnyxeForumItInitJs.parentNode));
			iFrameSrc += "&fg=" + encodeURIComponent(fgColor) + "&bg=" + encodeURIComponent(bgColor);

			iFrameSrc += "&isIframe=true";
			iFrameSrc += "&widgetFrameId=" + pnyxeForumItFrameId;
			iFrameSrc += "&v=1002"; // Used to force reload of the content of the widgets JSP files
			
			// GWT DevMode
			if (typeof(articleDetails.gwtCodeServer) != "undefined" && articleDetails.gwtCodeServer.length > 0) {
				iFrameSrc += "&gwt.codesvr=" + encodeURIComponent(articleDetails.gwtCodeServer);
			}
			
			// TalkAhead previewComment (MUST BE LAST PARAMETER)
			if (typeof(articleDetails.previewComment) != "undefined") {
				iFrameSrc += "&previewComment=" + articleDetails.previewComment;
			}
			
			// Setting the src with location.replace to force the browser (Firefox) to refresh pnyxe frame, otherwise, back and forward don't work.
			// Using setTimeout to allow the browser to complete rendering the HTML, otherwise invalid HTML interferes with location.replace (Chrome)
			pnyxeForumItFrame.tempSrc = iFrameSrc;
			setTimeout("document.getElementById(\"" + pnyxeForumItFrameId + "\").contentWindow.location.replace(document.getElementById(\"" + pnyxeForumItFrameId + "\").tempSrc)", 1);

			this.pnyxeCommon.initAutoResizeMechanism(pnyxeForumItFrameId, "pnyxeForumIt", pnyxeForumItFrameHeight);
		} catch (exception) {
			this.pnyxeCommon.logException("PnyxeForumIt.init", exception);
		}
	}
};



