/*
 *  Copyright 2015 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * Helper to register HTML zone into a page. Such a zone can be selected and highlighted.
 * @private
 */
Ext.define('Ametys.plugins.web.page.tool.UIZoneItem', {
	singleton: true,
	
	/**
	 * Register the HTML element zoneName in the document doc as a zone. If empty do some additional graphic.
	 * @param {HTMLElement} win The window where to work in
	 * @param {String} pageId The page identifier 
	 * @param {boolean} modifiable Is the zone modifiable ?
	 * @param {String} zoneName The id of the html element surrounding the zone
	 * @param {String} zoneItemHTMLId The id of the html element surrounding the zone
	 * @param {String} zoneItemId The id of the repository zone item
	 * @param {String} contentName If the zone item has a content, the content name is here
	 * @param {String} contentTypeOrServiceId If the zone item has a content, contains the content type ID. If the zone item has a service, the service id.
	 * @param {String} label The label of type of content
	 * @param {String} description The description of type of content
     * @param {String} iconGlyph The css class name to display a glyph as the icon of the zone
     * @param {String} iconDecorator The css class name to display a glyph decorator on the glyph 
	 * @param {String} smallIcon The path to the small icon
	 * @param {String} mediumIcon The path to the medium icon
	 * @param {String} largeIcon The path to the large icon
	 * @param {Boolean} sharedContent true if the content is a shared content.
	 */
	register: function(win, pageId, modifiable, zoneName, zoneItemHTMLId, zoneItemId, contentName, contentTypeOrServiceId, label, description, iconGlyph, iconDecorator, smallIcon, mediumIcon, largeIcon, sharedContent)
	{
	    var doc = win.document;
	    if (doc.zoneItems == null){ doc.zoneItems = []; }

	    doc.zoneItems.push({zoneName : zoneName, zoneItemHTMLId: zoneItemHTMLId, zoneItemId: zoneItemId});

	    
	    var div = doc.getElementById("ametys-cms-zone-" + zoneName + "-item-" + zoneItemHTMLId);
	    win.$j(div).addClass('ametys-cms-zone-item');
	    if (sharedContent)
	    {
	    	win.$j(div).addClass('ametys-cms-zone-item-shared-content');
	    }
	    div.setAttribute("zoneitem", zoneItemId);
	    div.setAttribute("zoneitem-type", contentName != "" ? 'content' : 'service');
	    div.setAttribute("zoneitem-type-id", contentTypeOrServiceId);
	    
	    var pageTool = pageId.startsWith('sitemap://') ?
	                       parent.Ametys.tool.ToolsManager.getTool('uitool-sitemappage$' + pageId) : 
	                       parent.Ametys.tool.ToolsManager.getTool('uitool-page$' + pageId);
	    Ametys.plugins.web.page.tool.UIZoneItem.highlight(win, zoneName, zoneItemHTMLId, zoneItemId, pageTool._lastZoneItemId == zoneItemId, true);
	    
	    var title = label 
	            + (contentName != "" ? (" (" + contentName + ")") : "")
	            + " : "
	            + description.replace(/<br\s*\/>/g,"\n");
	    
	    if (sharedContent)
	    {
	        var sharedHeaderDiv = doc.createElement('div');
	        win.$j(sharedHeaderDiv).addClass('ametys-cms-zone-item-shared-content-header').html("{{i18n PLUGINS_WEB_SKIN_UIZONEITEM_SHARED_CONTENT_HEADER}}");
	        div.insertBefore(sharedHeaderDiv, div.firstChild);
	    }
	    
    	var useGlyph = iconGlyph && iconGlyph != "";
    	var img = doc.createElement(useGlyph ? "span" : "img");
	    img.className = "ametys-cms-zone-item-grabber";
	    img.onclick = Ext.bind(parent.Ametys.plugins.web.page.tool.UIZoneItem.highlight, parent.Ametys.plugins.web.page.tool.UIZoneItem.highlight, [win, zoneName, zoneItemHTMLId, zoneItemId]);
	    img.title = title;
	    
	    if (useGlyph)
	    {
	    	img.className = "ametys-cms-zone-item-grabber " + [iconGlyph, iconDecorator].join(" ");
	    }
	    else
	    {
	    	if (smallIcon != null && smallIcon != "")
		    {
		        img.src = Ametys.CONTEXT_PATH + smallIcon;
		    }
		    else
		    {
		        img.src = Ametys.getPluginResourcesPrefix('web') + "/img/skin/zone_error_16.png";
		    }
	    }

	    div.insertBefore(img, div.firstChild);
	    
	    if (modifiable)
	    {
	        Ametys.plugins.web.page.tool.UIZoneItem.makesDraggable(win, pageId, div, img, label, contentName, zoneItemId, contentTypeOrServiceId);
	    }
	},
	
	/**
	 * Graphically highlight a zone
	 * @param {HTMLElement} win The window of the page
	 * @param {String} zoneName The id of the html element (div) of the zone to highlight in the document
	 * @param {String} zoneItemHTMLId The id of the html element surrounding the zone
	 * @param {String} zoneItemId The id of the repository zone item
	 * @param {Boolean} on Set to true to highlight or false to set normal 
	 * @param {Boolean} noEvent true to do not send events. false is default
	 */
	highlight: function(win, zoneName, zoneItemHTMLId, zoneItemId, on, noEvent) 
	{
	    var doc = win.document;
	    var div = doc.getElementById("ametys-cms-zone-" + zoneName + "-item-" + zoneItemHTMLId);

	    if (on == null)
	    {
	        on = !div.highlightState;
	    }
	    
	    if (on)
	    {
	        for (var i=0; i < doc.zones.length; i++)
	        {
	            var aZoneName = doc.zones[i];
	            Ametys.plugins.web.page.tool.UIZone.highlight(win, aZoneName, false, true);
	        }

	        // switch off other zones
	        for (var i=0; i < doc.zoneItems.length; i++)
	        {
	            var aZoneInfo = doc.zoneItems[i];
	            if (aZoneInfo.zoneItemId != zoneItemId)
	            {
	                Ametys.plugins.web.page.tool.UIZoneItem.highlight(win, aZoneInfo.zoneName, aZoneInfo.zoneItemHTMLId, aZoneInfo.zoneItemId, false, true);
	            }
	        }
	    }
	    
	    div.highlightState = on;

	    if (on)
	    {
	    	win.$j(div).addClass('ametys-cms-zone-item-selected');
	    }
	    else
	    {
	    	win.$j(div).removeClass('ametys-cms-zone-item-selected');
	    }
	    
	    if (noEvent != true)
	    {
	    	Ext.Function.defer(Ametys.plugins.web.page.tool.UIZoneItem._select, 1, Ametys.plugins.web.page.tool.UIZone._select, [win, on ? zoneItemId : null]);
	    }
	},
	
    /**
     * @private
     * Listener when the zone item is selected
     * @param {HTMLElement} win The window where to work in
     * @param {String} zoneItemId The id of the repository zone item
     */
	_select: function(win, zoneItemId)
	{
	    if (typeof win.onZoneSelected == "function")
	    {
	        win.onZoneSelected(null, zoneItemId, zoneItemId != null ? win.$j(win.document.body).find("div.ametys-cms-zone-item-selected").parent("div.ametys-cms-zone").outerWidth() : null);
	    }
	    else
	    {
	    	Ext.Function.defer(Ametys.plugins.web.page.tool.UIZoneItem._select, 5, Ametys.plugins.web.page.tool.UIZoneItem._select, [win, zoneItemId]);
	    }
	},
	
    /**
     * Makes a zoneitem draggable, so it can be dragged in another location
     * @param {HTMLElement} win The window where to work in
     * @param {String} pageId The page identifier 
     * @param {HTMLElement} div The zoneitem wrapping div element
     * @param {HTMLElement} img The zoneitem icon element
     * @param {String} label The label of type of content
     * @param {String} contentName If the zone item has a content, the content name is here
     * @param {String} zoneItemId The id of the repository zone item
     * @param {String} contentTypeOrServiceId If the zone item has a content, contains the content type ID. If the zone item has a service, the service id.
     */
	makesDraggable: function(win, pageId, div, img, label, contentName, zoneItemId, contentTypeOrServiceId)
    {
        // Default behavior : Nothing to do
        // Has to be overriden
    }
});