/*

 *  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.
 */

/**
 * This factory creates Ametys.message.MessageTarget for a page.
 * 
 * See #createTargets to know more.
 * @private
 */
Ext.define("Ametys.plugins.web.sitemap.SitemapMessageTargetFactory",
	{
		extend: "Ametys.message.factory.DefaultMessageTargetFactory",

		/**
		 * Create the targets for a message
		 * @param {Object} parameters The parameters needed by the factory to create the message. Can not be null. Handled elements are
		 * @param {String[]} parameters.id The sitemap's identifier. Must be present if sitemap is empty
		 * @param {Ametys.web.page.Page[]} parameters.sitemap The sitemap itself. Must be present if id is empty
		 * @param {Function} callback The callback function called when the target is created. Parameters are
		 * @param {Ametys.message.MessageTarget[]} callback.targets The targets created. Cannot be null.
		 */
		createTargets: function(parameters, callback)
		{
			if (parameters.id)
			{
                Ametys.web.sitemap.SitemapDAO.getSitemap (parameters.id, 
                                                        Ext.bind(this._createTargets, this, [callback, parameters], true),
                                                        null,
                                                        parameters['zone-name'], 
                                                        parameters['zoneitem-id']
                );
				
			}
			else if (parameters.sitemap)
			{
				this._createTargets (parameters.sitemap, callback, parameters);
			}
		},

		/**
		 * Create the sitemap target
		 * @param {Ametys.web.sitemap.Sitemap[]} sitemap The sitemap
		 * @param {Function} callback The callback function called when the targets are created. Parameters are
		 * @param {Ametys.message.MessageTarget[]} callback.targets The targets created. Cannot be null.
		 * @param {Object} parameters The initial parameters of the #createTargets method
		 * @private
		 */
		_createTargets: function (sitemap, callback, parameters)
		{
			delete parameters['id'];
			delete parameters['sitemap'];
			
			subtargets = this._createZoneTargets(sitemap, parameters['zone-name'], parameters['zoneitem-id'], parameters['content-id'], parameters['zone-width']);
			
			var target = Ext.create("Ametys.message.MessageTarget", {
				id: Ametys.message.MessageTarget.SITEMAP,
				parameters: sitemap.getProperties(parameters),
				subtargets: subtargets
			});
			
			callback([target]);
		},
		
        /**
         * @private
         * Create the zone subtarget
         * @param {Ametys.web.page.Page} page The parent page
         * @param {String} zoneName The zone name of subtarget to restrict to. Can be null be to create a subtarget for all zones.
         * @param {String} zoneItemId The id of zone item to restrict to. Can be null be to create a subtarget for all zone items.
         * @param {String} contentId The content id to restrict to. Can be null be to create a subtarget for all contents.
         * @param {Number} zoneWidth The width of parent zone.
         */
        _createZoneTargets: function (page, zoneName, zoneItemId, contentId, zoneWidth)
        {
            var targets = [];
            var zones = page.getZones();
            for (var z=0; z < zones.length; z++)
            {
                function passesCondition (zone, zoneName, zoneItemId)
                {
                    if (zoneItemId == null)
                    {
                        // Only look for zone to check condition
                        return zoneName == null || zone.name == zoneName;
                    }
                    
                    var zoneitems = zone.zoneitems;
                    for (var i=0; i < zoneitems.length; i++)
                    {
                        if (zoneitems[i].id == zoneItemId)
                        {
                            return true;
                        }
                    }
                    return false;
                }
                
                if (passesCondition(zones[z], zoneName, zoneItemId))
                {
                    var subtargets = this._createZoneItemTargets(zones[z], zoneItemId, contentId, zoneWidth);
                    targets.push(Ext.create("Ametys.message.MessageTarget", {
                        id: Ametys.message.MessageTarget.ZONE,
                        parameters: {
                            name: zones[z].name,
                            isModifiable: zones[z].isModifiable
                        },
                        subtargets: subtargets
                    }));
                }
            }
            
            return targets;
        },
        
        /**
         * @private
         * Create the zone item subtarget
         * @param {Object} zone The parent zone
         * @param {String} zoneItemId The id of zone item to restrict to. Can be null be to create a subtarget for all zone items.
         * @param {String} contentId The content id to restrict to. Can be null be to create a subtarget for all contents.
         * @param {Number} zoneWidth The width of parent zone.
         */
        _createZoneItemTargets: function (zone, zoneItemId, contentId, zoneWidth)
        {
            var targets = [];
            var zoneitems = zone.zoneitems;
            for (var z=0; z < zoneitems.length; z++)
            {
                if (zoneItemId == null || zoneitems[z].id == zoneItemId)
                {
                    var subtargets = [];
                    if (zoneitems[z].content)
                    {
                        if (contentId == null || zoneitems[z].content.id == contentId)
                        {
                            var content = Ext.create ('Ametys.cms.content.Content', Ext.apply(zoneitems[z].content, {'contentWidth': zoneWidth}));
                            subtargets.push(Ametys.plugins.cms.content.ContentMessageTargetFactory.createTarget(Ametys.message.MessageTarget.CONTENT, content));
                            
                        }

                        delete zoneitems[z].content;
                    }
                    
                    targets.push(Ext.create("Ametys.message.MessageTarget", {
                        id: Ametys.message.MessageTarget.ZONE_ITEM,
                        parameters: zoneitems[z],
                        subtargets: subtargets
                    }));
                }
            }
            
            return targets;
        }		
	}
);

Ext.define("Ametys.message.SitemapMessageTarget",
	{
		override: "Ametys.message.MessageTarget",
		
		statics: 
		{
			/**
			 * @member Ametys.message.MessageTarget
			 * @readonly
			 * @property {String} SITEMAP The target type is a sitemap. See Ametys.plugins.web.sitemap.SitemapMessageTargetFactory parameters to know more of the associated parameters. 
			 */
			SITEMAP: "sitemap"
		}
	}
);