/*
 * Copyright (C) 2003-2008 eXo Platform SAS.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see<http://www.gnu.org/licenses/>.
 */
package org.exoplatform.wcm.webui.search.config;

import java.util.ArrayList;
import java.util.List;

import javax.jcr.Node;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;

import org.exoplatform.ecm.webui.form.UIFormInputSetWithAction;
import org.exoplatform.ecm.webui.selector.UISelectable;
import org.exoplatform.services.cms.views.ApplicationTemplateManagerService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.wcm.webui.Utils;
import org.exoplatform.wcm.webui.search.UIWCMSearchPortlet;
import org.exoplatform.wcm.webui.selector.page.UIPageSelector;
import org.exoplatform.web.application.ApplicationMessage;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.application.portlet.PortletRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIApplication;
import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
import org.exoplatform.webui.core.model.SelectItemOption;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.form.UIForm;
import org.exoplatform.webui.form.UIFormSelectBox;
import org.exoplatform.webui.form.UIFormStringInput;

/*
 * Created by The eXo Platform SAS Author : Anh Do Ngoc anh.do@exoplatform.com
 * Oct 31, 2008
 */
@ComponentConfig(
	lifecycle = UIFormLifecycle.class, 
	template = "app:/groovy/webui/search/config/UISearchPageLayoutManager.gtmpl", 
	events = {
		@EventConfig(listeners = UISearchPageLayoutManager.SaveActionListener.class),
		@EventConfig(listeners = UISearchPageLayoutManager.SelectBasePathActionListener.class),
		@EventConfig(listeners = UISearchPageLayoutManager.CancelActionListener.class)
	}
)
public class UISearchPageLayoutManager extends UIForm  implements UISelectable {

	/** The Constant PORTLET_NAME. */
	public static final String	PORTLET_NAME												= "WCM Advance Search".intern();

	/** The Constant SEARCH_PAGE_LAYOUT_CATEGORY. */
	public static final String	SEARCH_PAGE_LAYOUT_CATEGORY					= "search-page-layout".intern();

	/** The Constant SEARCH_PAGE_LAYOUT_SELECTOR. */
	public static final String	SEARCH_PAGE_LAYOUT_SELECTOR					= "searchPageLayoutSelector".intern();

	/** The Constant SEARCH_FORM_TEMPLATE_CATEGORY. */
	public static final String	SEARCH_FORM_TEMPLATE_CATEGORY				= "search-form".intern();

	/** The Constant SEARCH_PAGINATOR_TEMPLATE_CATEGORY. */
	public static final String	SEARCH_PAGINATOR_TEMPLATE_CATEGORY	= "search-paginator";

	/** The Constant SEARCH_RESULT_TEMPLATE_CATEGORY. */
	public static final String	SEARCH_RESULT_TEMPLATE_CATEGORY			= "search-result";

	/** The Constant SEARCH_FORM_TEMPLATE_SELECTOR. */
	public static final String	SEARCH_FORM_TEMPLATE_SELECTOR				= "searchFormSelector";

	/** The Constant SEARCH_PAGINATOR_TEMPLATE_SELECTOR. */
	public static final String	SEARCH_PAGINATOR_TEMPLATE_SELECTOR	= "searchPaginatorSelector";

	/** The Constant SEARCH_RESULT_TEMPLATE_SELECTOR. */
	public static final String	SEARCH_RESULT_TEMPLATE_SELECTOR			= "searchResultSelector";

	/** The Constant ITEMS_PER_PAGE_SELECTOR. */
	public final static String	ITEMS_PER_PAGE_SELECTOR							= "itemsPerPageSelector";

	/** The Constant BASE_PATH_INPUT. */
  public final static String BASE_PATH_INPUT                 = "searchResultBasePathInput";

  /** The Constant BASE_PATH_SELECTOR_POPUP_WINDOW. */
  public final static String BASE_PATH_SELECTOR_POPUP_WINDOW = "searchResultBasePathPopupWindow";

  /** The Constant BASE_PATH_INPUT_SET_ACTION. */
  public final static String BASE_PATH_INPUT_SET_ACTION      = "searchResultBasePathInputSetAction";
  
  /** The popup id. */
  private String popupId;
	/**
   * @return the popupId
   */
  public String getPopupId() {
    return popupId;
  }

  /**
   * @param popupId the popupId to set
   */
  public void setPopupId(String popupId) {
    this.popupId = popupId;
  }

  /**
	 * Instantiates a new uI search page layout manager.
	 * 
	 * @throws Exception the exception
	 */
	public UISearchPageLayoutManager() throws Exception {
		PortletRequestContext portletRequestContext = WebuiRequestContext.getCurrentInstance();
		PortletPreferences portletPreferences = portletRequestContext.getRequest().getPreferences();

		String itemsPerpage = portletPreferences.getValue(UIWCMSearchPortlet.ITEMS_PER_PAGE, null);
		String searchFormTemplate = portletPreferences.getValue(UIWCMSearchPortlet.SEARCH_FORM_TEMPLATE_PATH,
																														null);
		String searchResultTemplate = portletPreferences.getValue(UIWCMSearchPortlet.SEARCH_RESULT_TEMPLATE_PATH,
																															null);
		String searchPaginatorTemplate = portletPreferences.getValue(	UIWCMSearchPortlet.SEARCH_PAGINATOR_TEMPLATE_PATH,
																																	null);
		String searchPageLayoutTemplate = portletPreferences.getValue(UIWCMSearchPortlet.SEARCH_PAGE_LAYOUT_TEMPLATE_PATH,
																																	null);		
		List<SelectItemOption<String>> searchFormTemplateList = createTemplateList(	PORTLET_NAME,
																																								SEARCH_FORM_TEMPLATE_CATEGORY);
		List<SelectItemOption<String>> searchResultTemplateList = createTemplateList(	PORTLET_NAME,
																																									SEARCH_RESULT_TEMPLATE_CATEGORY);
		List<SelectItemOption<String>> searchPaginatorTemplateList = createTemplateList(PORTLET_NAME,
																																										SEARCH_PAGINATOR_TEMPLATE_CATEGORY);
		List<SelectItemOption<String>> searchPageLayoutTemplateList = createTemplateList(	PORTLET_NAME,
																																											SEARCH_PAGE_LAYOUT_CATEGORY);
		List<SelectItemOption<String>> itemsPerPageList = new ArrayList<SelectItemOption<String>>();
		itemsPerPageList.add(new SelectItemOption<String>("5", "5"));
		itemsPerPageList.add(new SelectItemOption<String>("10", "10"));
		itemsPerPageList.add(new SelectItemOption<String>("20", "20"));

		UIFormSelectBox itemsPerPageSelector = new UIFormSelectBox(	ITEMS_PER_PAGE_SELECTOR,
																																ITEMS_PER_PAGE_SELECTOR,
																																itemsPerPageList);
		UIFormSelectBox searchFormTemplateSelector = new UIFormSelectBox(	SEARCH_FORM_TEMPLATE_SELECTOR,
																																			SEARCH_FORM_TEMPLATE_SELECTOR,
																																			searchFormTemplateList);
		UIFormSelectBox searchResultTemplateSelector = new UIFormSelectBox(	SEARCH_RESULT_TEMPLATE_SELECTOR,
																																				SEARCH_RESULT_TEMPLATE_SELECTOR,
																																				searchResultTemplateList);
		UIFormSelectBox searchPaginatorTemplateSelector = new UIFormSelectBox(SEARCH_PAGINATOR_TEMPLATE_SELECTOR,
																																					SEARCH_PAGINATOR_TEMPLATE_SELECTOR,
																																					searchPaginatorTemplateList);
		UIFormSelectBox searchPageLayoutTemplateSelector = new UIFormSelectBox(	SEARCH_PAGE_LAYOUT_SELECTOR,
																																						SEARCH_PAGE_LAYOUT_SELECTOR,
																																						searchPageLayoutTemplateList);		

		String preferenceBasePath = portletPreferences.getValue(UIWCMSearchPortlet.BASE_PATH, null);
    UIFormInputSetWithAction targetPathFormInputSet = new UIFormInputSetWithAction(BASE_PATH_INPUT_SET_ACTION);
    UIFormStringInput targetPathFormStringInput = new UIFormStringInput(BASE_PATH_INPUT, BASE_PATH_INPUT, preferenceBasePath);
    targetPathFormStringInput.setValue(preferenceBasePath);
    targetPathFormStringInput.setEditable(false);
    targetPathFormInputSet.setActionInfo(BASE_PATH_INPUT, new String[] {"SelectBasePath"}) ;
    targetPathFormInputSet.addUIFormInput(targetPathFormStringInput);
		
		itemsPerPageSelector.setValue(itemsPerpage);
		searchFormTemplateSelector.setValue(searchFormTemplate);
		searchResultTemplateSelector.setValue(searchResultTemplate);
		searchPaginatorTemplateSelector.setValue(searchPaginatorTemplate);
		searchPageLayoutTemplateSelector.setValue(searchPageLayoutTemplate);

		addChild(itemsPerPageSelector);		
		addChild(searchFormTemplateSelector);
		addChild(searchResultTemplateSelector);
		addChild(searchPaginatorTemplateSelector);
		addChild(searchPageLayoutTemplateSelector);
		addChild(targetPathFormInputSet);

		setActions(new String[] { "Save", "Cancel" });
	}

	/**
	 * Creates the template list.
	 * 
	 * @param portletName the portlet name
	 * @param category the category
	 * 
	 * @return the list< select item option< string>>
	 * 
	 * @throws Exception the exception
	 */
	private List<SelectItemOption<String>> createTemplateList(String portletName, String category) throws Exception {
		List<SelectItemOption<String>> templateList = new ArrayList<SelectItemOption<String>>();
		ApplicationTemplateManagerService templateManagerService = getApplicationComponent(ApplicationTemplateManagerService.class);
		RepositoryService repositoryService = getApplicationComponent(RepositoryService.class);
		ManageableRepository manageableRepository = repositoryService.getCurrentRepository();
		String repository = manageableRepository.getConfiguration().getName();
		List<Node> templateNodeList = templateManagerService.getTemplatesByCategory(repository,
																																								portletName,
																																								category,
																																								Utils.getSessionProvider());
		for (Node templateNode : templateNodeList) {
			String templateName = templateNode.getName();
			String templatePath = templateNode.getPath();
			templateList.add(new SelectItemOption<String>(templateName, templatePath));
		}
		return templateList;
	}

	/**
	 * The listener interface for receiving saveAction events. The class that is
	 * interested in processing a saveAction event implements this interface, and
	 * the object created with that class is registered with a component using the
	 * component's <code>addSaveActionListener<code> method. When
	 * the saveAction event occurs, that object's appropriate
	 * method is invoked.
	 * 
	 * @see SaveActionEvent
	 */
	public static class SaveActionListener extends EventListener<UISearchPageLayoutManager> {

		/*
		 * (non-Javadoc)
		 * @see
		 * org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui
		 * .event.Event)
		 */
		public void execute(Event<UISearchPageLayoutManager> event) throws Exception {
			UISearchPageLayoutManager uiSearchLayoutManager = event.getSource();
			UIApplication uiApp = uiSearchLayoutManager.getAncestorOfType(UIApplication.class);
			RepositoryService repositoryService = uiSearchLayoutManager.getApplicationComponent(RepositoryService.class);
			ManageableRepository manageableRepository = repositoryService.getCurrentRepository();
			String repository = manageableRepository.getConfiguration().getName();
			String workspace = manageableRepository.getConfiguration().getDefaultWorkspaceName();
			PortletRequestContext portletRequestContext = (PortletRequestContext) event.getRequestContext();
			PortletPreferences portletPreferences = portletRequestContext.getRequest().getPreferences();

			String searchResultTemplatePath = uiSearchLayoutManager	.getUIFormSelectBox(UISearchPageLayoutManager.SEARCH_RESULT_TEMPLATE_SELECTOR)
																															.getValue();
			String searchFormTemplatePath = uiSearchLayoutManager	.getUIFormSelectBox(UISearchPageLayoutManager.SEARCH_FORM_TEMPLATE_SELECTOR)
																														.getValue();
			String searchPaginatorTemplatePath = uiSearchLayoutManager.getUIFormSelectBox(UISearchPageLayoutManager.SEARCH_PAGINATOR_TEMPLATE_SELECTOR)
																																.getValue();
			String searchPageLayoutTemplatePath = uiSearchLayoutManager	.getUIFormSelectBox(UISearchPageLayoutManager.SEARCH_PAGE_LAYOUT_SELECTOR)
																																	.getValue();
			String itemsPerPage = uiSearchLayoutManager	.getUIFormSelectBox(UISearchPageLayoutManager.ITEMS_PER_PAGE_SELECTOR)
																									.getValue();
			
			String basePath = uiSearchLayoutManager.getUIStringInput(UISearchPageLayoutManager.BASE_PATH_INPUT).getValue();

			portletPreferences.setValue(UIWCMSearchPortlet.REPOSITORY, repository);
			portletPreferences.setValue(UIWCMSearchPortlet.WORKSPACE, workspace);			
			portletPreferences.setValue(UIWCMSearchPortlet.SEARCH_RESULT_TEMPLATE_PATH,
																	searchResultTemplatePath);
			portletPreferences.setValue(UIWCMSearchPortlet.SEARCH_FORM_TEMPLATE_PATH,
																	searchFormTemplatePath);
			portletPreferences.setValue(UIWCMSearchPortlet.SEARCH_PAGINATOR_TEMPLATE_PATH,
																	searchPaginatorTemplatePath);
			portletPreferences.setValue(UIWCMSearchPortlet.SEARCH_PAGE_LAYOUT_TEMPLATE_PATH,
																	searchPageLayoutTemplatePath);
			portletPreferences.setValue(UIWCMSearchPortlet.ITEMS_PER_PAGE, itemsPerPage);
			portletPreferences.setValue(UIWCMSearchPortlet.BASE_PATH, basePath);
			portletPreferences.store();
			
			if (Utils.isEditPortletInCreatePageWizard()) {
				uiApp.addMessage(new ApplicationMessage("UISearchConfig.msg.saving-success", null,ApplicationMessage.INFO));
			} else {
				portletRequestContext.setApplicationMode(PortletMode.VIEW);
			}
		}
	}

	/**
	 * The listener interface for receiving cancelAction events. The class that is
	 * interested in processing a cancelAction event implements this interface,
	 * and the object created with that class is registered with a component using
	 * the component's <code>addCancelActionListener<code> method. When
	 * the cancelAction event occurs, that object's appropriate
	 * method is invoked.
	 * 
	 * @see CancelActionEvent
	 */
	public static class CancelActionListener extends EventListener<UISearchPageLayoutManager> {

		/*
		 * (non-Javadoc)
		 * @see
		 * org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui
		 * .event.Event)
		 */
		public void execute(Event<UISearchPageLayoutManager> event) throws Exception {
			PortletRequestContext context = (PortletRequestContext) event.getRequestContext();
			context.setApplicationMode(PortletMode.VIEW);
		}
	}

	/*
   * (non-Javadoc)
   * 
   * @see org.exoplatform.ecm.webui.selector.UISelectable#doSelect(java.lang.String,
   *      java.lang.Object)
   */
  public void doSelect(String selectField, Object value) throws Exception {
    getUIStringInput(selectField).setValue((String) value);
    Utils.closePopupWindow(this, popupId);
  }
  
  /**
   * The listener interface for receiving selectTargetPageAction events.
   * The class that is interested in processing a selectTargetPageAction
   * event implements this interface, and the object created
   * with that class is registered with a component using the
   * component's <code>addSelectTargetPageActionListener<code> method. When
   * the selectTargetPageAction event occurs, that object's appropriate
   * method is invoked.
   * 
   * @see SelectTargetPageActionEvent
   */
  public static class SelectBasePathActionListener extends EventListener<UISearchPageLayoutManager> {
    
    /* (non-Javadoc)
     * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
     */
    public void execute(Event<UISearchPageLayoutManager> event) throws Exception {
      UISearchPageLayoutManager viewerManagementForm = event.getSource();
      UIPageSelector pageSelector = viewerManagementForm.createUIComponent(UIPageSelector.class, null, null);
      pageSelector.setSourceComponent(viewerManagementForm, new String[] {BASE_PATH_INPUT});
      Utils.createPopupWindow(viewerManagementForm, pageSelector, BASE_PATH_SELECTOR_POPUP_WINDOW, 800);
      viewerManagementForm.setPopupId(BASE_PATH_SELECTOR_POPUP_WINDOW);
    }
  }
}
