/*
 *  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 class is a singleton class to open a wizard for page creation
 * @private
 */
Ext.define('Ametys.plugins.web.page.AddPageWizard', {
	singleton: true,
	
	/**
     * @private
	 * @property {Ametys.plugins.web.page.AddPageWizard.Card[]} _cards The cards panel
	 */
	_cards: [],
	
    /**
     * @private
     * @property {String} _parentId The parent page or sitemap ID.
     */
    /**
     * @private
     * @property {String[]} _parentPages The input list of parent pages to choose from to find _parentId and _parent.
     */
    
    /**
     * @private
     * @property {Ametys.web.page.Page|Ametys.web.sitemap.Sitemap} _parent The parent page or sitemap
     */
    
	/**
	 * Open create page wizard
	 * 
	 * @param {String/String[]} parentId  the parent page or sitemap ID, or list of ids of page to choose from in a visual list.
	 * @param {Function} callback a callback function.
	 * @param {Ametys.web.page.Page} callback.page The page created. Can be null if an error occurred during creation.
	 * @param {Boolean} callback.success True if the full process is a success, false otherwise. Note that you can have a non-null page with a success to false.
	 * @param {Object} [config={}] The configuration of the wizard.
	 * 
     * @param {String} [config.icon-cls=ametysicon-website38 decorator-ametysicon-add64]           The CSS classes, separated by coma, to be applied to the icon element.
	 * @param {String} [config.icon-small] 	                                                    The url of the icon for the window (16x16). If null the 'icon-cls' will be used
	 * @param {String} [config.title=PLUGINS_WEB_CREATEPAGE_CAPTION] 							The dialog caption
	 * @param {String} [config.height=370]                                                          The dialog height
	 * @param {String} [config.width=530]                                                           The dialog width
	 * 
	 * @param {String} [config.right-settemplate=Web_Rights_Page_Templates] 					The right id to be allow to create a page with template
	 * @param {String} [config.right-setlinkpage=Web_Rights_Page_LinkPage] 					    The right id to be allow to create a page with redirection
	 * @param {String} [config.right-addcontent=Web_Rights_Page_AddContent] 					The right id to be allow to create a page with a content
	 * @param {String} [config.right-addservice=Web_Rights_Page_AddService] 					The right id to be allow to create a page with a service
	 * @param {String} [config.right-tag-page=Web_Rights_Page_Tag] 							    The right id to be allow to tag the new page with public page tags
	 * @param {String} [config.right-tag-privatepage=Web_Rights_Page_Private_Tag] 				The right id to be allow to tag the new page with private page tags
	 * @param {String} [config.right-tag-content=CMS_Rights_Content_Tag] 						The right id to be allow to tag the new content of the new page with public content tags
	 * @param {String} [config.right-tagprivate-content=CMS_Rights_Content_Private_Tag] 		The right id to be allow to tag the new content of the new page with private content tags
	 * 
	 * @param {String} [config.workflow-ANY] 						                            Any require worflow parameter to create a content. At least "workflow-workflowName"
     * @param {String} [config.workflow-workflowName=content]                                   The mandatory workflow paremeter
	 * @param {String} [config.workflowInitActionId=1]											The workflow action id to create the content. Such as 1.
     * @param {String} [config.workflowEditActionId=2]                                          The workflow action id to edit the content. Such as 2.
     * @param {String} [config.workflowInitAndEditActionId=11]                                  The workflow action id to create+edit the content. Such as 11.
     * 
     * @param {String} [viewName=default-edition]                                               The name of the view to use to edit the content. Default is default-edition.
	 * 
     * @param {String} [config.default-page-title=PLUGINS_WEB_CREATEPAGE_ACTIONS_NEWPAGE]       The default label for the new page
     * @param {String} [config.default-content-title=""]                                        The default title for a new content. If empty, the page long title will be used, or short title if no long titile is available
     * @param {String} [config.show-page-long-title=true]                                       True to display a field to enter the long page title
	 * @param {String} [config.default-pagetype]										        The default value for page-type between: 'template', 'redirection-cms', 'redirection-http' or 'blank'
	 * @param {String} [config.default-template] 											    The default selected template for the new page
     * @param {String} [config.default-zone=default]                                                    The default zone for the content
	 * @param {String} [config.default-pagecontent-type]							            The default pagecontent type between: 'contenttype' or 'service'.
	 * @param {String} [config.default-contenttype] 	                                        The default selected contenttype for the new content of the new page
	 * @param {String} [config.default-service]	                                                The default selected service for the new page
	 * @param {String} [config.default-tags]													The tags to check by default on the tags screen. E.g. ['FOOTER_LINKS', 'SPECIAL_PAGES']
     * 
     * @param {String} [config.default-selected-pagetype=template]                               The default value for page-type between: 'template', 'redirection-cms', 'redirection-http' or 'blank'
     * @param {String} [config.default-selected-template=page]                                   The default selected template for the new page
     * @param {String} [config.default-selected-zone=default]                                    The default zone for the content
     * @param {String} [config.default-selected-pagecontent-type=contenttype]                    The default pagecontent type between: 'contenttype' or 'service'.
     * @param {String} [config.default-selected-contenttype=org.ametys.web.default.Content.article]     The default selected contenttype for the new content of the new page
     * @param {String} [config.default-selected-service=org.ametys.web.service.FilteredContentsService] The default selected service for the new page
     * @param {String} [config.default-selected-tags]                                            The tags to check by default on the tags screen. E.g. ['FOOTER_LINKS', 'SPECIAL_PAGES']
	 * 
     * @param {String[]} [config.pagecontent-card-tags-categories-filter=null]                  List of tags to create a simplier version of the tag card, with several combo-box (one per item of this list)
     * @param {Boolean} [config.pagecontent-card-tags-categories-filter-only-subcategories=true]   True to display all categories in the lists, false to display only the leafs in the tree
     * @param {String} [config.pagecontent-card-tags-categories-filter-hierarchy-separator=" > "]   Separator between Parent > Child in the list
     *
	 * @param {String/Boolean} [config.force=false]                                             If 'true', when the OK button will be clicked, all next pages will be simulated. If false, the process will stop on the current page
     * @param {String/Boolean} [config.show-card-type=true]                                     If 'true', the page type card will be shown
     * @param {String/Boolean} [config.show-card-content=true]                                  If 'true', the page content card will be shown
     * @param {String/Boolean} [config.show-card-content-properties=false]                      If 'true', the page content properties card will be shown
     * @param {String/Boolean} [config.show-card-tags=true]                                     If 'true', the page tags card will be shown
     * 
	 * @param {String/Boolean} [config.pagetype-template=true]                                  If true, the typeCard wizard will show templates
	 * @param {String/Boolean} [config.pagetype-redirection-cms=true]                           If true, the typeCard wizard will show redirections inside the site
	 * @param {String/Boolean} [config.pagetype-redirection-http=true]                          If true, the typeCard wizard will show outside redirection
	 * @param {String/Boolean} [config.pagetype-blank=true]                                     If true, the typeCard wizard will show blank page
     * @param {String[]} [config.pagetype-card-template-filter=null]                            List of templates that can be displayed
     * 
     * @param {Number} [config.pagecontent-card-title-parent-hierarchy-count=0]                 Number of parents to display in the list of parents (if parentId is a list of ids)
     * @param {String} [config.pagecontent-card-title-parent-hierarchy-separator=" > "]         Separator Parent > Child in the list of parents (if parentId is a list of ids)
	 * 
	 * @param {String[]} [config.pagecontent-card-content-filter=null]                          List of content type identifiers that can be displayed. null for no filter
	 * @param {String/Boolean} [config.pagecontent-content=true]                                If true, the pageContent wizard will display content types
	 * @param {String[]} [config.pagecontent-card-service-filter=null]                          List of service Id that can be displayed. null for no filter
	 * @param {String/Boolean} [config.pagecontent-service=true]                                If true, the pageContent wizard will display services
     * 
     * @param {String} [config.content-createViewName=creation]                          Name of the metadataset used for creation
     * 
     * @param {Object} [config.i18n]                                                            All texts of the page creation wizard can be overridden
     * @param {Object} [config.i18n.main]                                                       Texts of the main wizard interface
     * @param {String} [config.i18n.main.error-title=PLUGINS_WEB_TOOL_PAGE_ACTIONS_ERRORTITLE]  Title of the error dialog
     * @param {String} [config.i18n.main.error-description=PLUGINS_WEB_TOOL_PAGE_ACTIONS_ERRORDESCRIPTION]  Description of the main error
     * @param {String} [config.i18n.main.button-previous=PLUGINS_WEB_CREATEPAGE_ACTIONS_PREVIOUS]   Previous button
     * @param {String} [config.i18n.main.button-next=PLUGINS_WEB_CREATEPAGE_ACTIONS_NEXT]       Next button
     * @param {String} [config.i18n.main.button-ok=PLUGINS_WEB_CREATEPAGE_ACTIONS_END]          End process buttor
     * @param {String} [config.i18n.main.button-next-forced=PLUGINS_WEB_CREATEPAGE_ACTIONS_NEXTFORCED]  End process (forced) button
     * @param {String} [config.i18n.main.button-cancel=PLUGINS_WEB_CREATEPAGE_ACTIONS_CANCEL]   Cancel button
     * @param {Object} [config.i18n.page]                                                       Texts of the page name card
     * @param {String} [config.i18n.page.parent-help=PLUGINS_WEB_CREATEPAGE_PARENT_HELP]        Help about parent paage
     * @param {String} [config.i18n.page.page-title-label=PLUGINS_WEB_CREATEPAGE_PARENT_TITLE]  Label of parent page field
     * @param {String} [config.i18n.page.title-help=PLUGINS_WEB_CREATEPAGE_CREATEPAGE_TITLE_HELP]   Help about page title
     * @param {String} [config.i18n.page.page-title=PLUGINS_WEB_CREATEPAGE_TITLE]               Label of page title field
     * @param {String} [config.i18n.page.page-title-regex-message=PLUGINS_WEB_CREATEPAGE_TITLE_REGEX_TEXT]  Errer message when the regex fails
     * @param {String} [config.i18n.page.hint=PLUGINS_WEB_CREATEPAGE_HINT]                      Hint about long title
     * @param {String} [config.i18n.page.page-long-title=PLUGINS_WEB_CREATEPAGE_TITLELONG]      Label of page long title field
     * @param {String} [config.i18n.page.hint2=PLUGINS_WEB_CREATEPAGE_HINT2]                    Hint about title/url
     * @param {String} [config.i18n.page.wait-message=PLUGINS_WEB_DAOS_PAGE_CREATE_WAITING_MSG] Wait message
     * @param {Object} [config.i18n.type]                                                       Texts of the page type card
     * @param {String} [config.i18n.type.template-wait-message=PLUGINS_WEB_DAOS_PAGE_SET_TEMPLATE_WAITING_MSG]  Wait message
     * @param {String} [config.i18n.type.link-error-title=PLUGINS_WEB_PAGE_LINKPAGE_ERRORTITLE] Error while redirection is created
     * @param {String} [config.i18n.type.link-error-message=PLUGINS_WEB_PAGE_LINKPAGE_REDIRECT_ITSELF_ERROR]  Message if the page tries to redirect to itself
     * @param {String} [config.i18n.type.link-wait-message=PLUGINS_WEB_DAOS_PAGE_LINKPAGE_WAITING_MSG]  Waiting message when creating a redirection
     * @param {String} [config.i18n.type.blank-wait-message=PLUGINS_WEB_DAOS_PAGE_LINKPAGE_WAITING_MSG] Waiting message when creating a blank page
     * @param {String} [config.i18n.type.template-title=PLUGINS_WEB_PAGE_TEMPLATESMENU_LABEL]   Title of the template selector
     * @param {String} [config.i18n.type.template-title-help=PLUGINS_WEB_CREATEPAGE_CHOOSETEMPLATE_TITLE_HELP]  Help about template
     * @param {String} [config.i18n.type.link-title=PLUGINS_WEB_PAGE_LINKPAGE_MENU_PAGE_LABEL]  Title of the redirection part
     * @param {String} [config.i18n.type.link-help=PLUGINS_WEB_CREATEPAGE_LINK_CMS_TITLE_HELP]  Help about redirection
     * @param {String} [config.i18n.type.web-link-title=PLUGINS_WEB_PAGE_LINKPAGE_MENU_WEB_LABEL]   Title of outside site redirection
     * @param {String} [config.i18n.type.web-link-description=PLUGINS_WEB_PAGE_LINKPAGE_WEBREDIRECTDESCRIPTION] Help about outside site redirection
     * @param {String} [config.i18n.type.web-link-help=PLUGINS_CORE_UI_HELPER_ENTERURL_LABEL]   Outside redirection help
     * @param {String} [config.i18n.type.web-link-hint=PLUGINS_CMS_HELPER_ENTERURL_HINT]        Outside redirection hint
     * @param {String} [config.i18n.type.blank-title=PLUGINS_WEB_RIGHTS_PAGE_BLANK_LABEL]       Blank page label
     * @param {String} [config.i18n.type.blank-help=PLUGINS_WEB_CREATEPAGE_PAGE_BLANK_TITLE_HELP]   Blank page help
     * @param {Object} [config.i18n.content]                                                    Texts of the content type / service selection card
     * @param {String} [config.i18n.content.content-type-title=PLUGINS_WEB_CONTENT_ADDCONTENTMENU_LABEL] Content part title
     * @param {String} [config.i18n.content.content-type-help=PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_TITLE_HELP] Content type help
     * @param {String} [config.i18n.content.content-type-nocontent=PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_NO_HELP] Text when there is no content type available at all
     * @param {String} [config.i18n.content.content-type-filter=PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_FILTER_HELP] Text in in the filter input of content types
     * @param {String} [config.i18n.content.content-type-filter-clear=PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_FILTERCANCEL_HELP] Tooltip of the clear filter button of content types
     * @param {String} [config.i18n.content.content-type-filter-noresult=PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_FILTER_NOVALUE] Text when there is no content type to choose after filtering
     * @param {String} [config.i18n.content.service-title=PLUGINS_WEB_CONTENT_ADDSERVICEMENU_LABEL] Service part title
     * @param {String} [config.i18n.content.service-help=PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_TITLE_HELP]   Service help
     * @param {String} [config.i18n.content.service-type-nocontent=PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_NO_HELP] Text when there is no service available at all
     * @param {String} [config.i18n.content.service-type-filter=PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_FILTER_HELP] Text in in the filter input of services
     * @param {String} [config.i18n.content.service-type-filter-clear=PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_FILTERCANCEL_HELP] Tooltip of the clear filter button of services
     * @param {String} [config.i18n.content.service-type-filter-noresult=PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_FILTER_NOVALUE] Text when there is no service to choose after filtering
     * @param {Object} [config.i18n.content-properties]                                         Text of the content properties card
     * @param {String} [config.i18n.content-properties.error-message=PLUGINS_CMS_CONTENT_UIHELPER_CREATECONTENT_FORMDEFINITION_ERROR]   Error message
     * @param {Object} [config.i18n.tags]                                                       Texts of the tags card
     * @param {String} [config.i18n.tags.help=PLUGINS_WEB_CREATEPAGE_TAGS_HELP]                 Tags selection help
     * @param {String} [config.i18n.tags.wait-message=PLUGINS_WEB_CREATEPAGE_TAGS_WAITING_MSG]  Waiting message
	 */
	open: function (parentId, callback, config)
	{
		this.config = Ext.applyIf(Ext.apply({}, config), {
	        'title': "{{i18n PLUGINS_WEB_CREATEPAGE_CAPTION}}",
            'icon-glyph': "ametysicon-website38",
            'icon-decorator': "decorator-ametysicon-add64",
            'icon-small': null,
            // Can't be set here to be able to detect later if the value was set by the caller
            // 'height' : 370, 
            // 'width' :530, 
            
			'workflowInitActionId': "1",
			'workflowEditActionId': "2",
            'workflowInitAndEditActionId' : "11",
            
            'viewName' : "default-edition",
			
	        'default-page-title': "{{i18n PLUGINS_WEB_CREATEPAGE_ACTIONS_NEWPAGE}}",
            'show-page-long-title' : true,
            'default-pagetype': null,
            'default-template': null,
            'default-zone': 'default',
            'default-pagecontent-type': null,
            'default-contenttype': null,
            'default-service': null,
            'default-tags': null,
            
	        'default-selected-pagetype': "template",
            'default-selected-template': "page",
            'default-selected-pagecontent-type': "contenttype",
            'default-selected-contenttype': "org.ametys.web.default.Content.article",
            'default-selected-service': "org.ametys.web.service.FilteredContentsService",
            'default-selected-tags': "",
	        
			'right-addcontent': "Web_Rights_Page_AddContent",
			'right-addservice': "Web_Rights_Page_AddService",
			'right-settemplate': "Web_Rights_Page_Templates",
			'right-setlinkpage': "Web_Rights_Page_LinkPage",
			'right-tag-page': "Web_Rights_Page_Tag",
	        'right-tagprivate-page': "Web_Rights_Page_Private_Tag",
	        'right-tag-content': "CMS_Rights_Content_Tag",
	        'right-tagprivate-content': "CMS_Rights_Content_Private_Tag",
	        
            'pagecontent-card-tags-categories-filter': null,
            'pagecontent-card-tags-categories-filter-only-subcategories': true,
            'pagecontent-card-tags-categories-filter-hierarchy-separator': " > ",
            
	        'force': "false",
            'show-card-type': true,
            'show-card-content': true,
            'show-card-content-properties': false,
            'show-card-tags': true,

	        'pagetype-template': true,
	        'pagetype-redirection-cms': true,
	        'pagetype-redirection-http': true,
	        'pagetype-blank' : true,
            'pagetype-card-template-filter' : null,
            
            'pagecontent-card-title-parent-hierarchy-count' : 0,
            'pagecontent-card-title-parent-hierarchy-separator' : " > ",

	        'pagecontent-card-content-filter' : null,
	        'pagecontent-content' : true,
	        'pagecontent-card-service-filter' : null,
	        'pagecontent-service' : true,
            
            'content-createViewName' : "creation"
        });
        
        // Default i18n values    
        var i18n = {
            'main' : {
                'error-title' : "{{i18n PLUGINS_WEB_TOOL_PAGE_ACTIONS_ERRORTITLE}}",
                'error-description' : "{{i18n PLUGINS_WEB_TOOL_PAGE_ACTIONS_ERRORDESCRIPTION}}",
                'button-previous' : "{{i18n PLUGINS_WEB_CREATEPAGE_ACTIONS_PREVIOUS}}",
                'button-next' : "{{i18n PLUGINS_WEB_CREATEPAGE_ACTIONS_NEXT}}",
                'button-ok' : "{{i18n PLUGINS_WEB_CREATEPAGE_ACTIONS_END}}",
                'button-next-forced' : "{{i18n PLUGINS_WEB_CREATEPAGE_ACTIONS_NEXTFORCED}}",
                'button-cancel' : "{{i18n PLUGINS_WEB_CREATEPAGE_ACTIONS_CANCEL}}"
            },
            'page' : {
                'parent-help' : "{{i18n PLUGINS_WEB_CREATEPAGE_PARENT_HELP}}",
                'page-title-label' : "{{i18n PLUGINS_WEB_CREATEPAGE_PARENT_TITLE}}",
                'title-help' : "{{i18n PLUGINS_WEB_CREATEPAGE_CREATEPAGE_TITLE_HELP}}",
                'page-title' : "{{i18n PLUGINS_WEB_CREATEPAGE_TITLE}}",
                'page-title-regex-message' : "{{i18n PLUGINS_WEB_CREATEPAGE_TITLE_REGEX_TEXT}}",
                'hint' : "{{i18n PLUGINS_WEB_CREATEPAGE_HINT}}",
                'page-long-title' : "{{i18n PLUGINS_WEB_CREATEPAGE_TITLELONG}}",
                'hint2' : "{{i18n PLUGINS_WEB_CREATEPAGE_HINT2}}",
                'wait-message' : "{{i18n PLUGINS_WEB_DAOS_PAGE_CREATE_WAITING_MSG}}"
            },
            'type' : {
                'template-wait-message' : "{{i18n PLUGINS_WEB_DAOS_PAGE_SET_TEMPLATE_WAITING_MSG}}",
                'link-error-title' : "{{i18n PLUGINS_WEB_PAGE_LINKPAGE_ERRORTITLE}}",
                'link-error-message' : "{{i18n PLUGINS_WEB_PAGE_LINKPAGE_REDIRECT_ITSELF_ERROR}}",
                'link-wait-message' : "{{i18n PLUGINS_WEB_DAOS_PAGE_LINKPAGE_WAITING_MSG}}",
                'blank-wait-message' : "{{i18n PLUGINS_WEB_DAOS_PAGE_LINKPAGE_WAITING_MSG}}",
                'template-title' : "{{i18n PLUGINS_WEB_PAGE_TEMPLATESMENU_LABEL}}",
                'template-title-help' : "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSETEMPLATE_TITLE_HELP}}",
                'link-title' : "{{i18n PLUGINS_WEB_PAGE_LINKPAGE_MENU_PAGE_LABEL}}",
                'link-help' : "{{i18n PLUGINS_WEB_CREATEPAGE_LINK_CMS_TITLE_HELP}}",
                'web-link-title' : "{{i18n PLUGINS_WEB_PAGE_LINKPAGE_MENU_WEB_LABEL}}",
                'web-link-description' : "{{i18n PLUGINS_WEB_PAGE_LINKPAGE_WEBREDIRECTDESCRIPTION}}",
                'web-link-help' : "{{i18n plugin.core-ui:PLUGINS_CORE_UI_HELPER_ENTERURL_LABEL}}",
                'web-link-hint' : "{{i18n plugin.cms:PLUGINS_CMS_HELPER_ENTERURL_HINT}}",
                'blank-title' : "{{i18n PLUGINS_WEB_RIGHTS_PAGE_BLANK_LABEL}}",
                'blank-help' : "{{i18n PLUGINS_WEB_CREATEPAGE_PAGE_BLANK_TITLE_HELP}}"
            },
            'content' : {
                'content-type-title' : "{{i18n PLUGINS_WEB_CONTENT_ADDCONTENTMENU_LABEL}}",
                'content-type-help' : "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_TITLE_HELP}}",
                'content-type-nocontent' : "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_NO_HELP}}",
                'content-type-filter': "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_FILTER_HELP}}",
                'content-type-filter-clear': "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_FILTERCANCEL_HELP}}",
                'content-type-filter-noresult': "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSECONTENT_FILTER_NOVALUE}}",

                'service-title' : "{{i18n PLUGINS_WEB_CONTENT_ADDSERVICEMENU_LABEL}}",
                'service-help' : "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_TITLE_HELP}}",
                'service-type-nocontent' : "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_NO_HELP}}",
                'service-type-filter': "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_FILTER_HELP}}",
                'service-type-filter-clear': "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_FILTERCANCEL_HELP}}",
                'service-type-filter-noresult': "{{i18n PLUGINS_WEB_CREATEPAGE_CHOOSESERVICE_FILTER_NOVALUE}}"
            },
            'content-properties' : {
                'error-message' : "{{i18n plugin.cms:PLUGINS_CMS_CONTENT_UIHELPER_CREATECONTENT_FORMDEFINITION_ERROR}}"
            },
            'tags' : {
                'help' : "{{i18n PLUGINS_WEB_CREATEPAGE_TAGS_HELP}}",
                'wait-message' : "{{i18n PLUGINS_WEB_CREATEPAGE_TAGS_WAITING_MSG}}"
            }
        }
        
        // apply default i18n values but check each level in the object
        
        if (!this.config['i18n'])
        {
            this.config['i18n'] = i18n;
        }
        else
        {
            for (card in i18n)
            {
                if (this.config['i18n'][card])
                {
                    this.config['i18n'][card] = Ext.applyIf(this.config['i18n'][card], i18n[card]);
                }
                else
                {
                    this.config['i18n'][card] = i18n[card];
                }
            }
        }
        
		
		this._callback = callback;
        this._contentId = null;
		if (!Ext.isFunction(this._callback))
		{
			this._callback = this._defaultCallBack;
		}
		this._pluginName = 'web';
        
        if (parentId != null)
        {
            parentId = parentId.split(";");
        }
        
        var callback = Ext.bind(this._showDialog, this);
        this.getPageInfos(parentId, Ext.bind(this._initPages, this, [callback], 1));
	},
    
    getPageInfos: function(parentId, callback)
    {
        if (!Array.isArray(parentId))
        {
            parentId = [parentId];
        }
        
        Ametys.data.ServerComm.callMethod({
                role: "org.ametys.web.repository.page.AddPageWizardHelper",
                methodName: "getPagesInfos",
                parameters: [parentId, this.config["pagecontent-card-title-parent-hierarchy-count"], this.config["pagecontent-card-title-parent-hierarchy-separator"]],
                callback: {
                    handler: callback,
                    scope: this
                },
                waitMessage: false,
                errorMessage: true
            });
    },
	
	getInitialConfig: function (name)
	{
		if (name)
		{
			return this.config[name];
		}
		else
		{
			return this.config;
		}
	},
	
    /**
     * Get the parent page or sitemap ID.
     * @return {String} page or sitemap id.
     */
    getParentId: function ()
    {
        return this._parentId;
    },
    
    /**
     * Get filtered list of parent ids if more than one was requested.
     * @return {String[]} page ids.
     */
    getParentPages: function ()
    {
        if (this._parentPages == null && this._parent != null)
        {
            return [this._parent];
        }
        else
        {
            return this._parentPages;
        }
    },

    /**
     * Get the parent page or sitemap
     * @return {Ametys.web.page.Page|Ametys.web.sitemap.Sitemap} _parent The parent page or sitemap
     */
	getParent: function ()
	{
		return this._parent;
	},
	
    /**
     * @private
     * Initialize the list of available parent pages
     * @param {Ametys.web.page.Page[]} pages
     * @param {Function} callback called after initialization
     */
    _initPages: function (pages, callback)
    {
        var availablePages = [];
        Ext.each(pages, function(page, index, array) {
            if (Array.isArray(page.rights) && page.rights.indexOf('Web_Rights_Page_Create') >= 0)
            {
                availablePages.push(page);
            }
        }, this);
        this._parentPages = availablePages;
        if (availablePages.length == 1)
        {
            var parentPage = availablePages[0];
            this._initRights(parentPage, callback);
        }
        else
        {
            if (Ext.isFunction(callback))
            {
                callback();
            }
        }
    },
	/**
	 * @private
	 * Initialize model from initial configuration and user's rights on parent page.
	 * @param {Ametys.web.page.Page|Ametys.web.sitemap.Sitemap} page The parent page or sitemap
	 */
	_initRights: function (page, callback)
	{
		if (page == null)
		{
			Ametys.log.ErrorDialog.display({
				title: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['main']['error-title'], 
				text: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['main']['error-description'],
	    		details: "The parent id '" + this._parentId + "' refers to an unknown existing page or sitemap",
	    		category: this.self.getName()
			});
	        throw "Invalid parent selection";
		}
		
		this._parent = page;
        this._parentId = page.id;
		this._model = {};
		
		this._model["right-template"] = Ext.Array.contains(page.rights, this.config["right-settemplate"]);
		this._model["right-link"] = Ext.Array.contains(page.rights, this.config["right-setlinkpage"]);
		
		this._model["right-contenttype"] = Ext.Array.contains(page.rights, this.config["right-addcontent"]);
		this._model["right-service"] = Ext.Array.contains(page.rights, this.config["right-addservice"]);

		this._model["right-tag-page"] = Ext.Array.contains(page.rights, this.config["right-tag-page"]);
		this._model["right-tag-page-private"] = Ext.Array.contains(page.rights, this.config["right-tagprivate-page"]);
		this._model["right-tag-content"] = Ext.Array.contains(page.rights, this.config["right-tag-content"]);
		this._model["right-tag-content-private"] = Ext.Array.contains(page.rights, this.config["right-tagprivate-content"]);
		this._model["right-tag"] = this._model["right-tag-page"] || this._model["right-tag-page-private"] || this._model["right-tag-content"] || this._model["right-tag-content-private"];

        this._updateButtons();
        
        if (Ext.isFunction(callback))
        {
            callback();
        }
	},
    
    _showDialog: function()
    {
        this.showDialog (this.config.title, this.config['icon-glyph'], this.config['icon-decorator'], this.config['icon-small'], this.config['height'], this.config['width']);
    },
	
    /**
     * Display the wizard
     * @param {String} title The dialog title
     * @param {String} iconGlyph A css class that will be used to display a top-left icon. Should use a glyph
     * @param {String} iconDecorator An additionnal css class that will be used to display a top-left icon. Should use a glyph decorator
     * @param {String} icon An image path to use as top-level icon. Exclusive with iconGlyph/iconDecorator
     * @param {String} [height=370] The dialog height, can be null.
     * @param {String} [width=530] The dialog width, can be null.
     */
	showDialog: function (title, iconGlyph, iconDecorator, icon, height, width)
	{
		this._delayedInitialize(title, [iconGlyph, iconDecorator].join(" ").trim(), icon, height, width);

        var barrierCallback = Ext.Function.createBarrier(this._cards.length, Ext.bind(this._showFirstCard, this));

		Ext.each(this._cards, function (card) {
			card.resetModel(barrierCallback);
		});
	},
	
	/**
     * @private
     * Show the box and the first card
     */
	_showFirstCard: function()
	{
	   this._box.show();
        
       this._showCard (0);
        
       var fieldsInFirstCard = this.getCurrentCard().getUI().down('field');
       if (fieldsInFirstCard)
       {
           window.setTimeout(function () { fieldsInFirstCard.focus(true); }, 1);
       }
	},
	
	/**
	 * Handler when clicking on 'previous' button
	 */
	previous: function()
	{
        if (!this._suspendModelUpdate)
        {
            this.getCurrentCard().updateModel();
        }

		this.goToPreviousCard();
	},

	/**
	 * Handler when clicking on 'next' button
	 */
	next: function()
	{
            if (!this._suspendModelUpdate)
            {
                this.getCurrentCard().updateModel();
            }
            this.goToNextCard();
	},

	/**
	 * Handler when clicking on 'cancel' button
	 */
	cancel: function()
	{
		this._box.hide();
	},

	/**
	 * Handler when clicking on 'Ok' button
	 */
	validate: function()
	{
        if (this._isForced())
        {
            this.forceValidate();
        }
        else
        {
    		if (!this._suspendModelUpdate)
            {
                this.getCurrentCard().updateModel();
            }
    
    		var fullModel = this.getModel();
			this._apply(fullModel, 0, this.getCurrentCardIndex());
        }
	},
    /**
     * Force the validation of ALL cards (the ones already validated, and also the future ones)
     */
    forceValidate: function()
    {
        if (!this._suspendModelUpdate)
        {
            this.getCurrentCard().updateModel();
        }

        var fullModel = this.getCompleteModel();
        this._apply(fullModel, 0, this.getCardsCount());
    },
	
	/**
	 * Get card to the specified index
	 * @param {Number} index The card index
	 * @return {Ametys.plugins.web.page.AddPageWizard.Card} the card if found.
	 */
	getCard: function(index)
	{
		return this._cards[index];
	},
	
	/**
	 * Get the number of cards
	 * @return {Number} the number of cards
	 */
	getCardsCount: function()
	{
		return this._cards.length;
	},
	
	/**
	 * Get the index of the current active card
	 * @return {Number} the index
	 */
	getCurrentCardIndex: function()
	{
		return this._box.items.indexOf(this._box.getLayout().activeItem);
	},
	
	/**
	 * Get the current active card
	 * @return {Ametys.plugins.web.page.AddPageWizard.Card} the actiave card
	 */
	getCurrentCard: function()
	{
		var currentCardIndex = this.getCurrentCardIndex();
		return this.getCard(currentCardIndex);
	},

	/**
	 * Go to the previous card
	 */
	goToPreviousCard: function()
	{
        var completeModel = this.getCompleteModel();
		var previousCardIndex = this._getPreviousCardIndex(completeModel);

		this.getCurrentCard().onLeave();
		this._showCard(previousCardIndex);
	},
	
	/**
	 * Go to the next card
	 */
	goToNextCard: function()
	{
        var completeModel = this.getCompleteModel();
		var nextCardIndex = this._getNextCardIndex(completeModel);

		this.getCurrentCard().onLeave();
		this._showCard(nextCardIndex);
	},
	
	/**
	 * Get the model
	 * @return {Object} the model
	 */
	getModel: function ()
	{
		var model = this.getAdditionnalModel();
		
		var currentCardIndex = this.getCurrentCardIndex();
		
		Ext.each(this._cards, function (card, index, array) {
			if (index <= currentCardIndex)
			{
				Ext.apply(model, card.getModel());
			}
		});
		
		return model;
	},
    /**
     * Get the model, containing also the values from future cards, not only those already validated
     * @return {Object} the model
     */
    getCompleteModel: function ()
    {
        var model = this.getAdditionnalModel();

        var currentCardIndex = this.getCurrentCardIndex();

        Ext.each(this._cards, function (card, index, array) {
            Ext.apply(model, card.getModel());
        });
        
        return model;
    },
	
    /**
     * Get the additionnal data to set in the model
     * @return {Object} model
     */
	getAdditionnalModel: function()
	{
		return Ext.apply({}, this._model);
	},

	/**
	 * Initialize wizard
	 * @param {String} title The dialog box 's title
     * @param {String} iconCls One or more space separated CSS classes to be applied to the icon element
	 * @param {String} icon The dialog box's icon path
     * @param {String} [height=370] The dialog height, can be null.
     * @param {String} [width=530] The dialog width, can be null.
	 */
    _delayedInitialize: function (title, iconCls, icon, height, width)
    {
        if (this._initialized)
        {
            this._box.setTitle(title);
            if (icon)
            {
                this._box.setIcon(Ametys.CONTEXT_PATH + icon);
            }
            else
            {
                this._box.setIconCls(iconCls);
            }
            return true;
        }

        this._cards.push(Ext.create ('Ametys.plugins.web.page.AddPageWizard.CreatePageCard', { box: this._box}));
        this._cards.push(Ext.create ('Ametys.plugins.web.page.AddPageWizard.PageTypeCard', { box: this._box }));
        this._cards.push(Ext.create ('Ametys.plugins.web.page.AddPageWizard.PageContentCard', { box: this._box }));
        if (this.config['show-card-content-properties'])
        {
            this._cards.push(Ext.create ('Ametys.plugins.web.page.AddPageWizard.ContentPropertiesCard', { box: this._box }));
        }
        if (this.config['pagecontent-card-tags-categories-filter'] != null && this.config['pagecontent-card-tags-categories-filter'].length > 0)
        {
            this._cards.push(Ext.create ('Ametys.plugins.web.page.AddPageWizard.TagsCardLite', { box: this._box }));
        }
        else
        {
            this._cards.push(Ext.create ('Ametys.plugins.web.page.AddPageWizard.TagsCard', { box: this._box }));
        }
		
		var cardItems = [];
		Ext.each(this._cards, function (card, index, array) {
			cardItems.push(card.createPanel());
		});
        
        var dialogWidth = width || 530;
        var dialogHeight = height || 370;
        if (!height && this._parentPages && this._parentPages.length > 1)
        {
            dialogHeight = 410;
        }
		
		this._box = Ext.create('Ametys.window.DialogBox', {
			title: title,
			icon: icon ? Ametys.CONTEXT_PATH + icon : null,
            iconCls: icon ? null : iconCls,
			
			width :dialogWidth,
			height: dialogHeight,
			minWidth: 530,
			minHeight: 250,
			maxWidth: window.innerWidth*0.8,
			maxHeight: window.innerHeight*0.8,
			scrollable: true,
			
			activeItem: 0,
			layout:'card',
			layoutConfig: {
				layoutOnCardChange: true
			},
			
			defaults: {
				cls: 'addpage-wizard-card'
			},
			
			items: cardItems,
			
			referenceHolder: true,
			defaultFocus: 'add-page-title',
			defaultButton: 'buttonNext',
			closeAction: 'hide',
			
			buttons : [{
					    	itemId: 'button-previous',
				            text: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['main']['button-previous'], 
				            handler : Ext.bind(this.previous, this)
						},
						{
							reference: 'buttonNext',
							itemId: 'button-next',
				            text: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['main']['button-next'],
				            handler : Ext.bind(this.next, this)
				        },
				        {
				        	reference: 'buttonOk',
				        	itemId: 'button-ok',
				        	text: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['main']['button-ok'],
				        	handler : Ext.bind(this.validate, this)
				        },
						{
				        	itemId: 'button-cancel',
							text: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['main']['button-cancel'],
							handler : Ext.bind(this.cancel, this)
						}
					]
		});
		
		this._initialized = true;
		return true;
	},
	
	/**
	 * @private
	 * Show card to the specified index
	 * @param {Number} index The index of card to activate
	 */
	_showCard: function(index)
	{
		this._box.getLayout().setActiveItem(index);	
		this.getCurrentCard().onEnter();
        
        this._box.down("button[itemId='button-next']").setDisabled(true);
        this._box.down("button[itemId='button-previous']").setDisabled(true);
        this._box.down("button[itemId='button-ok']").setDisabled(true);

        this._suspendModelUpdate = true;

        this.getCurrentCard().updateUI(Ext.bind(this._endUpdateUI, this));
	},
    
    /**
     * @private
     * Callback function to be called after updating UI of a card
     * @param {Boolean} success true if the UI was successfully updated
     */
    _endUpdateUI: function(success)
    {
        if (success)
        {
            this._suspendModelUpdate = false;
            this._updateButtons();
        }
    },
    
	/**
	 * @private
	 * Update dialog box buttons
	 */
	_updateButtons: function()
	{
        if (this._box)
        {
    		var fullModel = this.getModel();
            var completeModel = this.getCompleteModel();
    
    		// PREVIOUS BUTTON
    		var hasAPreviousCard = this._getPreviousCardIndex(completeModel) != -1;
    
    		var isCurrentCardOk = this.getCurrentCard().isModelOk(fullModel);
    
            // NEXT BUTTON
    		var hasANextCard = this._getNextCardIndex(completeModel) != -1;
    		
    		// OK BUTTON
            var isProcessOk = isCurrentCardOk && (this._isForced() || (this.getCurrentCard().isProcessOk(fullModel) || !hasANextCard));
            
    		// APPLY
    		var nextButton = this._box.down("button[itemId='button-next']");
    		var previousButton = this._box.down("button[itemId='button-previous']");
    		var okButton = this._box.down("button[itemId='button-ok']");
            
            var numberOfPages = this._numberOfAvailableCards();
    		
    		previousButton.setDisabled(!hasAPreviousCard);
    		nextButton.setDisabled(!hasANextCard || !isCurrentCardOk);
    		okButton.setDisabled(!isProcessOk);
    		
    		if (numberOfPages == 0)
    		{
    			previousButton.hide();
                nextButton.hide();
                okButton.setText(Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['main']['button-next-forced']);
    		}
    		else
    		{
    			previousButton.show();
                nextButton.show();
                okButton.setText(okButton.initialConfig.text);
    		}
        }
	},
	
    /**
     * @private
     * Return true if we are in a forced mode (config.force)
     * @return {Boolean} true if config.force == true
     */
    
    _isForced: function()
    {
        return (this.config["force"] == "true" || this.config["force"] === true);
    },
	/**
	 * @private
	 * Get the index of previous card
	 * @param {Object} fullModel The full model
	 * @return the index of previous card or -1 if there is no previous card
	 */
	_getPreviousCardIndex: function(fullModel)
	{
		var currentCardIndex = this._box.items.indexOf(this._box.getLayout().activeItem);
		for (var i = currentCardIndex - 1; i >= 0; i--)
		{
			var cardI = this._cards[i];
			if (cardI.shouldDisplayCard(fullModel))
			{
				return i;
			}
		}
		return -1;
	},
	
	/**
	 * @private
	 * Get the index of next card
	 * @param {Object} fullModel The full model
	 * @return the index of next card or -1 if there is no previous card
	 */
	_getNextCardIndex: function(fullModel)
	{
		var currentCardIndex = this._box.items.indexOf(this._box.getLayout().activeItem);
		for (var i = currentCardIndex + 1; i < this._cards.length; i++)
		{
			var cardI = this._cards[i];
			if (cardI.shouldDisplayCard(fullModel))
			{
				return i;
			}
		}
		return -1;
	},
    
    _numberOfAvailableCards: function()
    {
        var numberAvailable = 0;
        for (var i = 0 + 1; i < this._cards.length; i++)
        {
            var cardI = this._cards[i];
            if (cardI.displayCardInConf())
            {
                numberAvailable++;
            }
        }
        return numberAvailable;
    },

	/**
	 * @private
	 * Listener on any kind of changes.<br/>
	 * Updates models and buttons.
	 */
	_onChange: function()
	{
        if (!this._suspendModelUpdate)
        {
    		this.getCurrentCard().updateModel();
			this._updateButtons();
        }
	},
	
	/**
	 * @private
	 * Apply cards step recursively until last step.
	 * @param {Object} fullModel The full model representing all user's choices
	 * @param {Number} stepIndex The id of applied step
	 * @param {Number} maxStepIndex The maximum number of steps
	 */
	_apply: function (fullModel, stepIndex, maxStepIndex)
	{
		var callback = function(success)
		{
			if (success)
			{
				if (stepIndex < maxStepIndex)
				{
					this._apply(fullModel, stepIndex + 1, maxStepIndex);
				}
				else
				{
					this._box.hide();
					Ametys.plugins.web.page.AddPageWizard._callback (fullModel['page'], true);
				}
			}
			else
			{
				this._box.hide();
				Ametys.plugins.web.page.AddPageWizard._callback (fullModel['page'], false);
			}
		}
		
		var card = this.getCard(stepIndex);
		if (!card || !card.isAvailable(fullModel))
		{
			callback.call(this, [true]);
		}
		else
		{
			card.apply(fullModel, Ext.bind(callback, this));
		}
	},

	/**
	 * @private
	 * Default callback when the page is created, open a tool
	 * @param {Ametys.web.page.Page} page The created page
	 */
	_defaultCallBack: function(page)
	{
		Ametys.tool.ToolsManager.openTool ('uitool-page', {id: page.getId()});
        if (this._contentId)
        {
          Ametys.tool.ToolsManager.openTool ('uitool-content', {
            id: this._contentId,
            'mode': 'edit',
            "workflow-action": Ametys.plugins.web.page.AddPageWizard.getInitialConfig('workflowEditActionId'),
            "view-name": Ametys.plugins.web.page.AddPageWizard.getInitialConfig('viewName')});
        }
	}

});