/*
 * Copyright (C) 2003-2009 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.newsletter.manager;

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

import javax.jcr.Node;

import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.wcm.newsletter.NewsletterCategoryConfig;
import org.exoplatform.services.wcm.newsletter.NewsletterManagerService;
import org.exoplatform.services.wcm.newsletter.NewsletterSubscriptionConfig;
import org.exoplatform.services.wcm.newsletter.handler.NewsletterCategoryHandler;
import org.exoplatform.services.wcm.newsletter.handler.NewsletterSubscriptionHandler;
import org.exoplatform.services.wcm.newsletter.handler.NewsletterTemplateHandler;
import org.exoplatform.wcm.webui.Utils;
import org.exoplatform.wcm.webui.newsletter.UINewsletterConstant;
import org.exoplatform.web.application.ApplicationMessage;
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.UIFormDateTimeInput;
import org.exoplatform.webui.form.UIFormSelectBox;

/**
 * Created by The eXo Platform SAS
 * Author : eXoPlatform
 * chuong.phan@exoplatform.com, phan.le.thanh.chuong@gmail.com
 * Jun 12, 2009
 */
@ComponentConfig (
                  lifecycle = UIFormLifecycle.class,
                  template = "app:/groovy/webui/newsletter/NewsletterManager/UINewsletterEntryDialogSelector.gtmpl",
                  events = {
                    @EventConfig (listeners = UINewsletterEntryDialogSelector.UpdateNewsletterActionListener.class),
                    @EventConfig (listeners = UINewsletterEntryDialogSelector.OpenWebcontentSelectorFormActionListener.class),
                    @EventConfig (listeners = UINewsletterEntryDialogSelector.ChangeTemplateActionListener.class),
                    @EventConfig (listeners = UINewsletterEntryDialogSelector.ChangeCategoryActionListener.class)
                  }
)
public class UINewsletterEntryDialogSelector extends UIForm {

  /** The Constant NEWSLETTER_ENTRY_TEMPLATE. */
  public static final String NEWSLETTER_ENTRY_TEMPLATE = "UINewsletterEntryTemplate";

  /** The Constant NEWSLETTER_ENTRY_SEND_DATE. */
  public static final String NEWSLETTER_ENTRY_SEND_DATE = "UINewsletterEntrySendDate";

  /** The dialog. */
  private String dialog = "dialog1";

  /**
   * Gets the dialog.
   * 
   * @return the dialog
   */
  public String getDialog() {
    return dialog;
  }

  /**
   * Sets the dialog.
   * 
   * @param dialog the new dialog
   */
  public void setDialog(String dialog) {
    this.dialog = dialog;
  }

  /**
   * Instantiates a new uI newsletter entry dialog selector.
   * 
   * @throws Exception the exception
   */
  public UINewsletterEntryDialogSelector() throws Exception {
    this.setActions(new String[]{"UpdateNewsletter"});
    UIFormSelectBox newsletterEntryTemplate = new UIFormSelectBox(NEWSLETTER_ENTRY_TEMPLATE, NEWSLETTER_ENTRY_TEMPLATE, new ArrayList<SelectItemOption<String>>());
    newsletterEntryTemplate.setOnChange("ChangeTemplate");
    addChild(newsletterEntryTemplate);
    addUIFormInput(new UIFormDateTimeInput(NEWSLETTER_ENTRY_SEND_DATE, NEWSLETTER_ENTRY_SEND_DATE, null, true));
  }

  /**
   * Inits the.
   * 
   * @param CategoryName the category name
   * @param subScriptionName the sub scription name
   * 
   * @throws Exception the exception
   */
  public void init(String CategoryName, String subScriptionName) throws Exception{
    NewsletterManagerService newsletterManagerService = getApplicationComponent(NewsletterManagerService.class);
    NewsletterCategoryHandler newsletterCategoryHandler = newsletterManagerService.getCategoryHandler();
    SessionProvider sessionProvider = Utils.getSessionProvider();
    String portalName = NewsLetterUtil.getPortalName();
    List<NewsletterCategoryConfig> newsletterCategoryConfigs = newsletterCategoryHandler.getListCategories(portalName, 
                                                                                                           sessionProvider);
    List<SelectItemOption<String>> categories = new ArrayList<SelectItemOption<String>>();
    for (NewsletterCategoryConfig newsletterCategoryConfig : newsletterCategoryConfigs) {
      categories.add(new SelectItemOption<String>(newsletterCategoryConfig.getTitle(), newsletterCategoryConfig.getName()));
    }
    UIFormSelectBox categorySelectBox = new UIFormSelectBox(UINewsletterConstant.ENTRY_CATEGORY_SELECTBOX, 
                                                            UINewsletterConstant.ENTRY_CATEGORY_SELECTBOX, categories);
    categorySelectBox.setOnChange("ChangeCategory");
    if(CategoryName != null && CategoryName.trim().length() > 0){
      categorySelectBox.setValue(CategoryName);
      categorySelectBox.setDisabled(true);
    }
    
    if(CategoryName == null) CategoryName = categories.get(0).getValue();
    NewsletterSubscriptionHandler newsletterSubscriptionHandler = newsletterManagerService.getSubscriptionHandler();
    List<NewsletterSubscriptionConfig> listSubscriptions = 
                                              newsletterSubscriptionHandler.getSubscriptionsByCategory(sessionProvider, portalName, 
                                                                                                       CategoryName);
    List<SelectItemOption<String>> subscriptions = new ArrayList<SelectItemOption<String>>();
    for (NewsletterSubscriptionConfig newsletterSubscriptionConfig : listSubscriptions) {
      subscriptions.add(new SelectItemOption<String>(newsletterSubscriptionConfig.getTitle(), newsletterSubscriptionConfig.getName()));
    }
    UIFormSelectBox subscriptionSelectBox = new UIFormSelectBox(UINewsletterConstant.ENTRY_SUBSCRIPTION_SELECTBOX, 
                                                                UINewsletterConstant.ENTRY_SUBSCRIPTION_SELECTBOX, subscriptions);
    if(subScriptionName != null && subScriptionName.trim().length() > 0){
      subscriptionSelectBox.setValue(subScriptionName);
      subscriptionSelectBox.setDisabled(true);
    }
    
    addChild(categorySelectBox);
    addChild(subscriptionSelectBox);
    NewsletterCategoryConfig categoryConfig = getAncestorOfType(UINewsletterEntryContainer.class).getCategoryConfig();
    if(categoryConfig == null)
      categoryConfig = newsletterCategoryConfigs.get(0);
    updateTemplateSelectBox(categoryConfig);
  }

  /**
   * Update template select box.
   * 
   * @param categoryConfig the category config
   * 
   * @throws Exception the exception
   */
  public void updateTemplateSelectBox(NewsletterCategoryConfig categoryConfig) throws Exception {
    List<SelectItemOption<String>> templates = new ArrayList<SelectItemOption<String>>();
    NewsletterManagerService newsletterManagerService = getApplicationComponent(NewsletterManagerService.class);
    NewsletterTemplateHandler newsletterTemplateHandler = newsletterManagerService.getTemplateHandler();
    List<Node> templateNodes = newsletterTemplateHandler.getTemplates(
                                                                      Utils.getSessionProvider(),
                                                                      NewsLetterUtil.getPortalName(), 
                                                                      categoryConfig);
    for (Node template : templateNodes) {
      templates.add(new SelectItemOption<String>(template.getProperty("exo:title").getString(), template.getName()));
    }
    getUIFormSelectBox(NEWSLETTER_ENTRY_TEMPLATE).setOptions(templates);
  }

  /**
   * The listener interface for receiving changeTemplateAction events.
   * The class that is interested in processing a changeTemplateAction
   * event implements this interface, and the object created
   * with that class is registered with a component using the
   * component's <code>addChangeTemplateActionListener<code> method. When
   * the changeTemplateAction event occurs, that object's appropriate
   * method is invoked.
   * 
   * @see ChangeTemplateActionEvent
   */
  public static class ChangeTemplateActionListener extends EventListener<UINewsletterEntryDialogSelector> {
    
    /* (non-Javadoc)
     * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
     */
    public void execute(Event<UINewsletterEntryDialogSelector> event) throws Exception {
      UINewsletterEntryDialogSelector newsletterEntryDialogSelector = event.getSource();
      UIFormSelectBox newsletterEntryTemplate = newsletterEntryDialogSelector.getChildById(NEWSLETTER_ENTRY_TEMPLATE);
      String templateName = newsletterEntryTemplate.getValue();
      newsletterEntryDialogSelector.setDialog(templateName) ;
      NewsletterManagerService newsletterManagerService = newsletterEntryDialogSelector.getApplicationComponent(NewsletterManagerService.class);
      NewsletterTemplateHandler newsletterTemplateHandler = newsletterManagerService.getTemplateHandler();
      UINewsletterEntryContainer newsletterEntryContainer = newsletterEntryDialogSelector.getAncestorOfType(UINewsletterEntryContainer.class);
      UINewsletterEntryForm newsletterEntryForm = newsletterEntryContainer.getChild(UINewsletterEntryForm.class) ;
      newsletterEntryForm.setNodePath(newsletterTemplateHandler.getTemplate(
                                                                            Utils.getSessionProvider(),
                                                                            NewsLetterUtil.getPortalName(), 
                                                                            newsletterEntryContainer.getCategoryConfig(), 
                                                                            templateName).getPath());
      newsletterEntryForm.getChildren().clear();
      newsletterEntryForm.resetProperties();
      event.getRequestContext().addUIComponentToUpdateByAjax(newsletterEntryContainer) ;
      newsletterEntryTemplate.setValue(templateName);
    }
  }

  /**
   * The listener interface for receiving openWebcontentSelectorFormAction events.
   * The class that is interested in processing a openWebcontentSelectorFormAction
   * event implements this interface, and the object created
   * with that class is registered with a component using the
   * component's <code>addOpenWebcontentSelectorFormActionListener<code> method. When
   * the openWebcontentSelectorFormAction event occurs, that object's appropriate
   * method is invoked.
   * 
   * @see OpenWebcontentSelectorFormActionEvent
   */
  public static class OpenWebcontentSelectorFormActionListener extends EventListener<UINewsletterEntryDialogSelector> {
    
    /* (non-Javadoc)
     * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
     */
    public void execute(Event<UINewsletterEntryDialogSelector> event) throws Exception {
      UINewsletterEntryDialogSelector newsletterEntryDialogSelector = event.getSource();
      UINewsletterEntryWebcontentSelectorForm newsletterEntryWebcontentSelector = newsletterEntryDialogSelector.createUIComponent(UINewsletterEntryWebcontentSelectorForm.class, null, null);
      Utils.createPopupWindow(newsletterEntryDialogSelector, newsletterEntryWebcontentSelector, UINewsletterConstant.WEBCONTENT_SELECTOR_FORM_POPUP_WINDOW, 300);
    }
  }

  /**
   * The listener interface for receiving changeCategoryAction events.
   * The class that is interested in processing a changeCategoryAction
   * event implements this interface, and the object created
   * with that class is registered with a component using the
   * component's <code>addChangeCategoryActionListener<code> method. When
   * the changeCategoryAction event occurs, that object's appropriate
   * method is invoked.
   * 
   * @see ChangeCategoryActionEvent
   */
  public static class ChangeCategoryActionListener extends EventListener<UINewsletterEntryDialogSelector> {
    
    /* (non-Javadoc)
     * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
     */
    public void execute(Event<UINewsletterEntryDialogSelector> event) throws Exception {
      UINewsletterEntryDialogSelector newsletterEntryDialogSelector = event.getSource();

      UINewsletterEntryContainer newsletterEntryContainer = newsletterEntryDialogSelector.getAncestorOfType(UINewsletterEntryContainer.class);

      UIFormSelectBox categorySelectBox = newsletterEntryDialogSelector.getChildById(UINewsletterConstant.ENTRY_CATEGORY_SELECTBOX);
      List<SelectItemOption<String>> subscriptions = new ArrayList<SelectItemOption<String>>();
      NewsletterManagerService newsletterManagerService = newsletterEntryDialogSelector.getApplicationComponent(NewsletterManagerService.class);
      NewsletterSubscriptionHandler newsletterSubscriptionHandler = newsletterManagerService.getSubscriptionHandler();
      String portalName = NewsLetterUtil.getPortalName();
      SessionProvider sessionProvider = Utils.getSessionProvider();
      NewsletterCategoryConfig categoryConfig = newsletterManagerService.getCategoryHandler().getCategoryByName(sessionProvider, portalName, 
                                                                                                                categorySelectBox.getValue());
      List<NewsletterSubscriptionConfig> newsletterSubscriptionConfigs = 
              newsletterSubscriptionHandler.getSubscriptionsByCategory(sessionProvider, portalName, categorySelectBox.getValue());
      for (NewsletterSubscriptionConfig newsletterSubscriptionConfig : newsletterSubscriptionConfigs) {
        subscriptions.add(new SelectItemOption<String>(newsletterSubscriptionConfig.getTitle(), newsletterSubscriptionConfig.getName()));
      }

      UIFormSelectBox subscriptionSelectBox = newsletterEntryDialogSelector.getChildById(UINewsletterConstant.ENTRY_SUBSCRIPTION_SELECTBOX);
      subscriptionSelectBox.setOptions(subscriptions);
      newsletterEntryDialogSelector.updateTemplateSelectBox(categoryConfig);
      event.getRequestContext().addUIComponentToUpdateByAjax(newsletterEntryContainer) ;
    }
  }

  /**
   * The listener interface for receiving updateNewsletterAction events.
   * The class that is interested in processing a updateNewsletterAction
   * event implements this interface, and the object created
   * with that class is registered with a component using the
   * component's <code>addUpdateNewsletterActionListener<code> method. When
   * the updateNewsletterAction event occurs, that object's appropriate
   * method is invoked.
   * 
   * @see UpdateNewsletterActionEvent
   */
  public static class UpdateNewsletterActionListener extends EventListener<UINewsletterEntryDialogSelector> {
    
    /* (non-Javadoc)
     * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
     */
    public void execute(Event<UINewsletterEntryDialogSelector> event) throws Exception {
      UINewsletterEntryDialogSelector newsletterEntryDialogSelector = event.getSource();
      UIFormSelectBox newsletterEntryTemplate = newsletterEntryDialogSelector.getChildById(NEWSLETTER_ENTRY_TEMPLATE);
      String templateName = newsletterEntryTemplate.getValue();
      UIFormDateTimeInput formDateTimeInput = newsletterEntryDialogSelector.getChild(UIFormDateTimeInput.class);
      Calendar calendar = formDateTimeInput.getCalendar();
      
      UIFormSelectBox categorySelectBox = newsletterEntryDialogSelector.getChildById("UINewsletterEntryCategorySelectBox");
      UIFormSelectBox subcriptionSelectBox = newsletterEntryDialogSelector.getChildById("UINewsletterEntrySubscriptionSelectBox");
     
      UINewsletterEntryContainer entryContainer = newsletterEntryDialogSelector.getAncestorOfType(UINewsletterEntryContainer.class);
      UIApplication uiApp = entryContainer.getAncestorOfType(UIApplication.class);
      if(calendar == null || formDateTimeInput.getValue().trim().length() < 1){
        if(formDateTimeInput.getValue() == null || formDateTimeInput.getValue().trim().length() < 1){
          uiApp.addMessage(new ApplicationMessage("UINewsletterEntryForm.msg.DateTimeIsNotNull", null, ApplicationMessage.WARNING));
        }else {
          uiApp.addMessage(new ApplicationMessage("UINewsletterEntryForm.msg.DateTimeIsInvalid", null, ApplicationMessage.WARNING));
        }
        event.getRequestContext().addUIComponentToUpdateByAjax(uiApp.getUIPopupMessages());
        return;
      }
      if (categorySelectBox.getValue() == null || subcriptionSelectBox.getValue() == null
      		|| categorySelectBox.getValue().toString() == "" || subcriptionSelectBox.getValue().toString() == "")
      {
      	Utils.createPopupMessage(newsletterEntryDialogSelector, "UINewsletterEntryDialogSelector.msg.subcriptionIsNotEmpty", null, ApplicationMessage.WARNING);
      	return;
      }
      
      entryContainer.setUpdated(true);
      formDateTimeInput.setCalendar(calendar);
      uiApp.addMessage(new ApplicationMessage("UINewsletterEntryForm.msg.UpdateInformationSuccessful", null, ApplicationMessage.INFO));
      event.getRequestContext().addUIComponentToUpdateByAjax(newsletterEntryDialogSelector) ;
      newsletterEntryTemplate.setValue(templateName);
    }
  }
}
