/**
 * Copyright (C) 2009 eXo Platform SAS.
 * 
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 * 
 * This software 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.exoplatform.webui.organization;

import org.exoplatform.commons.utils.LazyPageList;
import org.exoplatform.commons.utils.SerializablePageList;
import org.exoplatform.services.organization.Group;
import org.exoplatform.services.organization.GroupHandler;
import org.exoplatform.services.organization.MembershipType;
import org.exoplatform.services.organization.MembershipTypeHandler;
import org.exoplatform.services.organization.OrganizationService;
import org.exoplatform.services.organization.User;
import org.exoplatform.commons.serialization.api.annotations.Serialized;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIGrid;
import org.exoplatform.webui.core.UIPageIterator;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.event.Event.Phase;
import org.exoplatform.webui.form.UIForm;
import org.exoplatform.webui.form.UIFormPopupWindow;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Created by The eXo Platform SARL
 * Author : Tuan Nguyen
 *          tuan08@users.sourceforge.net
 * Jun 26, 2006
 * 
 */
@ComponentConfig(template = "system:/groovy/organization/webui/component/UIUserMembershipSelector.gtmpl", events = {
   @EventConfig(listeners = UIUserMembershipSelector.SelectMembershipActionListener.class),
   @EventConfig(listeners = UIUserMembershipSelector.DeleteMembershipActionListener.class, phase = Phase.DECODE, confirm = "UIUserMembershipSelector.deleteMembership")})
@Serialized
public class UIUserMembershipSelector extends UISelector<String>
{

   private List<Membership> membership_ = new ArrayList<Membership>();

   private String user_ = "site";

   private boolean isAdminRole_ = false;

   public static final String[] BEAN_FIELD = {"userName", "groupId", "membershipType"};

   public static final String[] ACTIONS = {"DeleteMembership"};

   public UIUserMembershipSelector() throws Exception
   {
      super("UIUserMembershipSelector", null);
      setComponentConfig(UIUserMembershipSelector.class, null);
      UIGrid uiGrid = addChild(UIGrid.class, null, "MembershipGrid");
      uiGrid.configure("id", BEAN_FIELD, ACTIONS);

      UIFormPopupWindow uiPopup = addChild(UIFormPopupWindow.class, null, "UserPermissionSelector");
      uiPopup.setWindowSize(540, 0);
      UIGroupMembershipSelector uiMembershipSelector = createUIComponent(UIGroupMembershipSelector.class, null, null);
      uiPopup.setUIComponent(uiMembershipSelector);
   }

   public String getUser()
   {
      return user_;
   }

   public void setUserName(String userName) throws Exception
   {
      user_ = userName;
   }

   public Class<String> getTypeValue()
   {
      return String.class;
   }

   public boolean isAdminRole()
   {
      return isAdminRole_;
   }

   public void setAdminRole(boolean b)
   {
      isAdminRole_ = b;
   }

   @SuppressWarnings("unchecked")
   public void setUser(User user) throws Exception
   {
      user_ = user.getUserName();
      membership_.clear();
      OrganizationService service = getApplicationComponent(OrganizationService.class);
      Collection<org.exoplatform.services.organization.Membership> collection =
         service.getMembershipHandler().findMembershipsByUser(user_);
      for (org.exoplatform.services.organization.Membership membership : collection)
      {
         addMembership(new Membership(membership.getUserName(), membership.getId(), membership.getGroupId(), membership
            .getMembershipType()));
      }

      UIGrid uiGrid = getChild(UIGrid.class);

      SerializablePageList pageList = new SerializablePageList(new MembershipListAccess(getMembership()), 10);

      uiGrid.getUIPageIterator().setPageList(pageList);
   }

   public List<Membership> getMembership()
   {
      return membership_;
   }

   public void createMembership(String groupId, String membershipType)
   {
      Membership membership = new Membership(user_, "", groupId, membershipType);
      addMembership(membership);
   }

   public void addMembership(Membership mem)
   {
      String groupId, membershipType = null;
      for (Membership ele : membership_)
      {
         groupId = ele.getGroupId();
         membershipType = ele.getMembershipType();
         if (groupId.equals(mem.getGroupId()) && membershipType.equals(mem.getMembershipType()))
            return;
      }
      membership_.add(mem);
   }

   public void setUIInputValue(Object input)
   {
      user_ = (String)input;
   }

   public void save(OrganizationService service, boolean broadcast) throws Exception
   {
      GroupHandler groupHandler = service.getGroupHandler();
      MembershipTypeHandler mtHandler = service.getMembershipTypeHandler();
      User user = service.getUserHandler().findUserByName(user_);
      for (Membership membership : membership_)
      {
         if (user == null)
            user = service.getUserHandler().findUserByName(membership.getUserName());
         Group group = groupHandler.findGroupById(membership.getGroupId());
         MembershipType mt = mtHandler.findMembershipType(membership.getMembershipType());
         if (service.getMembershipHandler() != null)
         {
            service.getMembershipHandler().linkMembership(user, group, mt, broadcast);
         }
      }
   }

   void setMembership(String groupId, String membershipType)
   {
      createMembership(groupId, membershipType);
   }

   public String event(String actionName, String beanId) throws Exception
   {
      UIForm uiForm = getAncestorOfType(UIForm.class);
      if (uiForm != null)
         return uiForm.event(actionName, getId(), beanId);
      return super.event(name, beanId);
   }

   static public class DeleteMembershipActionListener extends EventListener<UIUserMembershipSelector>
   {
      public void execute(Event<UIUserMembershipSelector> event) throws Exception
      {
         UIUserMembershipSelector uiUserMembershipSelector = event.getSource();
         String id = event.getRequestContext().getRequestParameter(OBJECTID);
         UIPageIterator pageIterator = uiUserMembershipSelector.getChild(UIGrid.class).getUIPageIterator();
         int currentPage = pageIterator.getCurrentPage();
         OrganizationService service = uiUserMembershipSelector.getApplicationComponent(OrganizationService.class);
         service.getMembershipHandler().removeMembership(id, true);
         User user = service.getUserHandler().findUserByName(uiUserMembershipSelector.getUser());
         uiUserMembershipSelector.setUser(user);
         while (currentPage > pageIterator.getAvailablePage())
            currentPage--;
         pageIterator.setCurrentPage(currentPage);
      }
   }

   static public class Membership implements Serializable
   {

      private String groupId_;

      private String membershipType_;

      private String userName_;

      private String id_;

      public Membership(String userName, String id, String groupId, String membershipType)
      {
         userName_ = userName;
         id_ = id;
         groupId_ = groupId;
         membershipType_ = membershipType;
      }

      public Membership(String userName, String groupId, String membershipType)
      {
         this(userName, "", groupId, membershipType);
      }

      public String getId()
      {
         return id_;
      }

      public void setId(String id)
      {
         id_ = id;
      }

      public String getUserName()
      {
         return userName_;
      }

      public void setUserName(String userName)
      {
         userName_ = userName;
      }

      public String getGroupId()
      {
         return groupId_;
      }

      public void setGroupId(String groupId)
      {
         groupId_ = groupId;
      }

      public String getMembershipType()
      {
         return membershipType_;
      }

      public void setMembershipType(String membershipType)
      {
         membershipType_ = membershipType;
      }
   }

}
