/** public class SneezeGuards : Encapsulates collection of all guarded content in the page. */
var SneezeGuards = {};
/** public void add : adds a new SneezeGuard object to the collection. */
SneezeGuards.add = function(guardId){
    this[guardId] = new SneezeGuard(guardId);
}

/** public class SneezeGuard : Encapsulates the pieces of a sneezeguard, which is
 * basically a DHTML screen protecting an area of content from user clicks.
 * @param String id Unique id of the content area
 */
SneezeGuard = function(id){
    this.id = id;
    this.element = document.getElementById(id);
    this.guard = document.getElementById(id.replace(/_wrapper$/, "_sneezeguard"));
    this.guard.style.height = this.element.offsetHeight + "px";
    this.guard.style.position = "absolute";
    this.guard.style.display = "block";
    this.tip = document.getElementById(id.replace(/_wrapper$/, "_tiptext"));
}
/** public static void over : Initializes the sneezeguard the 1st time content area
 * is moused over. Starts the countdown for displaying the tooltip, if necessary.
 * @param Event e Mouseover event triggering the method call
 * @param String id Unique id of the moused over content area
 */
SneezeGuard.over = function(e, id){
    e.cancelBubble = true;
    if (!SneezeGuards[id]) {
        SneezeGuards.add(id);
    }
    if (SneezeGuards[id].tip) {
        window.tipTimeout = setTimeout("SneezeGuards['" + id + "'].tip.style.display = 'inline';", 500);
    }
}

/** public static void out : Cancels the countdown for displaying the tooltip.
 * @param Event e Mouseout event triggering the method call
 * @param String id Unique id of the moused over content area
 */
SneezeGuard.out = function(e, id){
    e.cancelBubble = true;
    SneezeGuards[id].tip.style.display = "none";
    clearTimeout(tipTimeout);
}

/** public static class EditedPage: wrapper for any actions needed to prepare
 * a page when it edit mode.
 */
EditedPage = {
    /** public static void init : execute actions on page load. */
    init: function(){
        // disable all select objects in a page, to compensate for the IE bug
        for (var i = 0; i < document.getElementsByTagName("SELECT").length; i++) {
            document.getElementsByTagName("SELECT")[i].disabled = true;
        }
		
		/* Editable Widgets - create sneezeguards */
		var widgets = jQuery("div.CobaltEditableWidget");
		var hasWidgets = (widgets.length > 0);
		if (hasWidgets) {
			CobaltWSM.editableWidgetManager.init();
			jQuery.each(widgets, function(){
				CobaltWSM.editableWidgetManager.addSneezeguard(this);
			});
		}
    }
}

/******************************************************************************************/
/* Editable Widgets API   */
/******************************************************************************************/

var CobaltWSM = window.CobaltWSM || {};

CobaltWSM.editableWidgetSneezeguard = function(id) {
    this.id = id;
    this.element = document.getElementById(id);
	this.width = 0;
	this.height = 0;
	this.toolTip = null;
	this.guard = null;
	this.init();
}
CobaltWSM.editableWidgetSneezeguard.prototype = {
	MIN_WIDTH : 100,
	MIN_HEIGHT : 50,
	//
	init : function() {
		var wrapperCss = CobaltWSM.editableWidgetManager.getWrapperDisplayCss();
		var jObj = jQuery(this.element);
		jObj.css(wrapperCss);
		
		this.guard = this.getSneezeguard();
		this.setDimensions();
		
		this.toolTip = this.getToolTip();
		this.toolTip.prependTo(jObj);
		this.guard.prependTo(jObj);
		this.setHeight(this.height + this.toolTip.height());
	},
	getToolTip : function() {        
		return jQuery("<div>").addClass("wsm_tip_editableWidget").html('<img align="top" src="' + ContextManager.getAssetServerUrl() + '/websites/websitesEar/websitemanagerWebApp/wsm/images/icon_editcell_off.gif"><span class="editableWidget_tiptext">Click to edit</span>');
	},
	getSneezeguard : function() {
		var _this = this; // use closure to maintain reference
		var sg = jQuery('<div></div>').addClass('editableWidget_sneezeguard');
		
		sg.bind('mouseover', function(event) {
			_this.over(event, this);
		});
		sg.bind('mouseout', function(event) {
			_this.out(event, this);
		});
		sg.bind('click', function(event) {
			_this.click(event, this);
		});
		return sg;
	},
	setDimensions : function() {
		var jObj = jQuery(this.element);
		//reset wrapper w/h in case contents have re-sized - we want to measure what's inside
		// 	It's tricky to get the correct width/height values when the wrapper already has style w/h set.
		var wVal = (jQuery.browser.msie) ? this.MIN_WIDTH : "auto";
		var hVal = (jQuery.browser.msie) ? this.MIN_HEIGHT : "auto";
		jObj.css("width", wVal);
		jObj.css("height", hVal);
		
		var xmlWidth = null;
		var xmlHeight = null;
		var widthPrefix = CobaltWSM.editableWidgetManager.getWidthPrefix();
		var heightPrefix = CobaltWSM.editableWidgetManager.getHeightPrefix();
		var classes = jObj.attr("class").split(" ");
		for (var i = 0; i < classes.length; i++) {
			if (classes[i].indexOf(widthPrefix) != -1) {
				xmlWidth = parseInt(classes[i].replace(widthPrefix, ""));
				continue;
			}
			if (classes[i].indexOf(heightPrefix) != -1) {
				xmlHeight = parseInt(classes[i].replace(heightPrefix, ""));
				continue;
			}
		}
		//Default wrapper dimension
		var w = jObj.width(),
			h = jObj.height();
		var ow = this.element.offsetWidth,
			 oh = this.element.offsetHeight;
		w = (xmlWidth) ? ((ow > xmlWidth) ? ow : xmlWidth) : w;
		h = (xmlHeight) ? ((oh > xmlHeight) ? oh : xmlHeight) : h;
		// Check for minimum
		var width = (w < this.MIN_WIDTH) ? this.MIN_WIDTH : w;
		var height = (h < this.MIN_HEIGHT) ? this.MIN_HEIGHT : h;
		this.setWidth(width);
		this.setHeight(height);
	},
	setWidth : function(w) {
		this.width = w;
		this.guard.css("width", w);
		jQuery(this.element).css("width", w);
	},
	setHeight : function(h) {
		this.height = h;
		this.guard.css("height", h);
		jQuery(this.element).css("height", h);
	},
	stopPropagation : function(e) {
        if (e && e.stopPropagation) {
            e.stopPropagation();
        }
        else {
            window.event.cancelBubble = true;
        }
    },
	over : function(e, elem){
		this.stopPropagation(e);
		this.guard.addClass("editableWidget_sneezeguard_over");
		this.toolTip.find("span").addClass("editableWidget_tiptext_over");
	},
	out : function(e, elem){
		this.stopPropagation(e);
		this.guard.removeClass("editableWidget_sneezeguard_over");
		this.toolTip.find("span").removeClass("editableWidget_tiptext_over");
	},
	click : function(e, elem){
		var id = this.id;
		this.stopPropagation(e);
		var containerName = jQuery("#" + id).parents("div.wsm_lockedCell, div.wsm_editableCell").attr("id");
		var cellName = containerName.substring(0, containerName.indexOf("_wrapper"));
		var pageName = ContextManager.getPageName();
		var widgetName = id.substring(0, id.length - CobaltWSM.editableWidgetManager.getInstanceNameLength()).replace(/_+/g, ' ');
		var widgetInstanceName = id.substring(id.length - CobaltWSM.editableWidgetManager.getInstanceNameLength());
		new ModalDialog('/websitemanager/widgetConfigurator.do?cellName=' + cellName + '&widgetName=' + widgetName + '&pageName=' + pageName + '&widgetInstanceName=' + widgetInstanceName, 'lrg').open();
		return false;
	}
}

CobaltWSM.editableWidgetManager = function(){
    var _WIDGET_INSTANCE_NAME_LENGTH = 10;
	var _widthPrefix = "width_";
	var _heightPrefix = "height_";
	
	var _isInstanceId = function(id) {
		return (!isNaN(parseInt(id)) && (id.length == _WIDGET_INSTANCE_NAME_LENGTH));
	}
	/*****************************************/
	var _wrapperDisplayCss = {};
	
	// determine treatment for wrapper DIV to get correct width measurement
	var _setWrapperDisplayCss = function() {
		if ((jQuery.browser.msie) && ((parseInt(jQuery.browser.version) < 8) || (document.compatMode == "BackCompat"))) {
			// IE 8 in quirks mode takes this setting
			_wrapperDisplayCss = {"display":"inline", "zoom":"1"};	
		} else {
			_wrapperDisplayCss = {"display":"inline-block"};
		}
	}
	/*****************************************/
	var _sneezeguards = {};
	
	/*****************************************/
	// When a widget updates itself, this method will be called. Resize the sneezeguard.
	var _updateWidget = function(ev, pubData) {
		if (!pubData || !pubData.instanceId) return;
		var id = pubData.instanceId;
		if (_sneezeguards[id]) {
			_sneezeguards[id].setDimensions();
		}
	}
	/*****************************************/
	
    return {
		init : function() {
			_setWrapperDisplayCss();
			OpenAjax.hub.subscribe("com.cobaltgroup.ws.widget.update", _updateWidget, this);
			OpenAjax.hub.subscribe("com.cobaltgroup.ws.widget.update.**", _updateWidget, this);
		},
		addSneezeguard : function(elem) {
			var id = jQuery(elem).attr("id");
			var instanceIdSt = id.substring(id.length - _WIDGET_INSTANCE_NAME_LENGTH);
			// confirm that it has an instance ID. If so, add the sneezeguard.
			if (_isInstanceId(instanceIdSt)) {
				_sneezeguards[instanceIdSt] = new CobaltWSM.editableWidgetSneezeguard(id);
			}
		},
		getWrapperDisplayCss : function() {
			return _wrapperDisplayCss;
		},
		getWidthPrefix : function() { return _widthPrefix; },
		getHeightPrefix : function() { return _heightPrefix; },
		getInstanceNameLength : function() { return _WIDGET_INSTANCE_NAME_LENGTH; }
    };
}();

