/*
 * $Id: RegisterGroupForm.java,v 1.3 2005/10/05 17:02:23 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: RegisterGroupForm.java,v $
 * Revision 1.3  2005/10/05 17:02:23  marbobo
 * + Anzeigen von Kategorie oder Dokementnamen
 *
 * Revision 1.2  2005/10/03 17:33:32  marbobo
 * + Komplett-Überarbeitet und viele Fehler korrigiert
 *
 *
 */
package vkc.view.form;

import java.text.CollationKey;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;

import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCDocument;
import vkc.db.serializer.VKCCategorySerializer;
import vkc.db.serializer.VKCDocumentSerializer;
import vkc.db.serializer.VKCGroupSerializer;
import vkc.db.serializer.VKCUserSerializer;
import vkc.exception.DBException;
import vkc.misc.VKCLogManager;
import vkc.util.VKCStringUtils;
import vkc.view.bean.GroupInfo;
import vkc.view.bean.UserInfo;
import vkc.view.form.BasicActionForm;

/**
 * Form Bean zum registrieren von Documenten und Kategorien für bestimmte Gruppen und Benutzer
 */
public final class RegisterGroupForm extends BasicActionForm {
    private Integer categoryId = null;
    private Integer documentId = null;

    private Integer[] addGroupIds = new Integer[0];
    private Integer[] selectedAddGroupIds = new Integer[0];
    private Integer[] selectedRemoveGroupIds = new Integer[0];

    private Integer[] addUserIds = new Integer[0];
    private Integer[] selectedAddUserIds = new Integer[0];
    private Integer[] selectedRemoveUserIds = new Integer[0];

    private List addGroupLabels = new ArrayList();
    private List removeGroupLabels = new ArrayList();
    private List groupInfos = null;

    private List addUserLabels = new ArrayList();
    private List removeUserLabels = new ArrayList();
    private List userInfos = null;

    private VKCCategory category = null;
    
    private VKCDocument document = null;

    /**
     * Reset der Eingabefelder auf Defaultwerte
     * 
     * @param mapping The mapping used to select this instance
     * @param request The servlet request we are processing
     */
    public void reset(ActionMapping mapping, HttpServletRequest request) {
        super.reset(mapping, request);

        categoryId = null;
        documentId = null;

        addGroupIds = new Integer[0];
        selectedAddGroupIds = new Integer[0];
        selectedRemoveGroupIds = new Integer[0];

        addUserIds = new Integer[0];
        selectedAddUserIds = new Integer[0];
        selectedRemoveUserIds = new Integer[0];

        addGroupLabels = new ArrayList();
        removeGroupLabels = new ArrayList();
        groupInfos = null;

        addUserLabels = new ArrayList();
        removeUserLabels = new ArrayList();
        userInfos = null;

        category = null;
        
        document = null;
    }

    /**
     * Validiert die Eingabefelder und gibt gegebenfalls die Fehler zurück
     * 
     * @param mapping The mapping used to select this instance
     * @param request The servlet request we are processing
     */
    public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        
        if (request.getParameter("action.register.group") != null) {
            synchronizeForm(request);
        }

        return errors;
    }

    public void synchronizeForm(HttpServletRequest request) {
        try {
            if (request.getParameter("initialize") != null) {
                HashSet userIds = new HashSet(Arrays.asList(getAddUserIds()));
                userIds.add(getUser().getUserId());
                setAddUserIds((Integer[])userIds.toArray(new Integer[0]));
            }

            List userInfos = getUserInfos();
            List addUserLabels = new ArrayList();
            List removeUserLabels = new ArrayList();
			Integer[] addUserIds = getAddUserIds();
            
            for (int i = 0; i < addUserIds.length; i++) {
                for (int j = 0; j < userInfos.size(); j++) {
                    UserInfo u = (UserInfo) userInfos.get(j);

                    if (addUserIds[i].equals(u.getUserId())) {
                    	addUserLabels.add(u);
                        userInfos.remove(j);
                        break;
                    }
                }
            }

            removeUserLabels = userInfos;
            
			final Collator collator = Collator.getInstance(getUser().getLanguage().getLocale());

			Comparator lastname_c = new Comparator() {
				public int compare(Object o1, Object o2) {
					UserInfo u1 = (UserInfo) o1;
					UserInfo u2 = (UserInfo) o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(u1.getLastname()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(u2.getLastname()));
                	
                	return key1.compareTo(key2);
				}
			};

            Collections.sort(addUserLabels, lastname_c);
            Collections.sort(removeUserLabels, lastname_c);
            setAddUserLabels(addUserLabels);
            setRemoveUserLabels(removeUserLabels);

            List groupInfos = getGroupInfos();
            List addGroupLabels = new ArrayList();
            List removeGroupLabels = new ArrayList();
            Integer[] addGroupIds = getAddGroupIds();
            
            for (int i = 0; i < addGroupIds.length; i++) {
                for (int j = 0; j < groupInfos.size(); j++) {
                    GroupInfo g = (GroupInfo) groupInfos.get(j);

                    if (addGroupIds[i].equals(g.getGroupId())) {
                        addGroupLabels.add(g);
                        groupInfos.remove(j);
                        break;
                    }
                }
            }

            removeGroupLabels = groupInfos;
            
			Comparator groupname_c = new Comparator() {
				public int compare(Object o1, Object o2) {
					GroupInfo g1 = (GroupInfo)o1;
					GroupInfo g2 = (GroupInfo)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(g1.getName()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(g2.getName()));
                	
                	return key1.compareTo(key2);
				}
			};

            Collections.sort(addGroupLabels, groupname_c);
            Collections.sort(removeGroupLabels, groupname_c);
            setAddGroupLabels(addGroupLabels);
            setRemoveGroupLabels(removeGroupLabels);
        } catch (DBException e) {
            VKCLogManager.errorLog(this, "", e.getMessage(), e);
        }
    }

    public List getAddGroupLabels() {
        return addGroupLabels;
    }

    public List getRemoveGroupLabels() {
        return removeGroupLabels;
    }

    public Integer[] getSelectedAddGroupIds() {
        return selectedAddGroupIds;
    }

    public Integer[] getSelectedRemoveGroupIds() {
        return selectedRemoveGroupIds;
    }

    public void setAddGroupLabels(List list) {
        addGroupLabels = list;
    }

    public void setRemoveGroupLabels(List list) {
        removeGroupLabels = list;
    }

    public void setAddGroupIds(Integer[] integers) {
        addGroupIds = integers;
    }

    public void setSelectedAddGroupIds(Integer[] ids) {
        selectedAddGroupIds = ids;
    }

    public void setSelectedRemoveGroupIds(Integer[] ids) {
        selectedRemoveGroupIds = ids;
    }

    public Integer[] getAddGroupIds() {
        return addGroupIds;
    }

    public String getRedirectPath() {
    	if (isRegisterCategory()) {
    		return "/showCategory.do?categoryId=" + getCategoryId();
    	} else if (isRegisterDocument()) {
    		return "/showCategory.do?categoryId=" + getCategoryId() + "&anchor=doc" + getDocumentId();
    	} else {
    		return "/showCategory.do";
    	}
    }

    public List getGroupInfos() throws DBException {
        if (groupInfos == null) {
            groupInfos = new ArrayList();

            if (getUser().hasAdminPrivileges()) {
            	groupInfos = VKCGroupSerializer.retrieveGroupInfos();
            } else if (getUser().isDedicatedGroupsAdmin()) {
            	groupInfos = VKCGroupSerializer.retrieveGroupInfosByCreator(getUser().getUserId());
            }
        }
        
        return groupInfos;
    }

    public List getUserInfos() throws DBException {
        if (userInfos == null) {
            userInfos = new ArrayList();

            if (getUser().hasAdminPrivileges()) {
            	userInfos = VKCUserSerializer.retrieveUserInfos();
            } else if (getUser().isDedicatedUsersAdmin()) {
            	userInfos = VKCUserSerializer.retrieveUserInfosByCreator(getUser().getUserId());
            }
            
            UserInfo u = VKCUserSerializer.retrieveUserInfo(getUser().getUserId());
            
            if (!userInfos.contains(u)) {
            	userInfos.add(u);
            }
        }
        
        return userInfos;
    }

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public Integer getDocumentId() {
        return documentId;
    }

    public void setDocumentId(Integer documentId) {
        this.documentId = documentId;
    }

    public Integer[] getAddUserIds() {
        return addUserIds;
    }

    public void setAddUserIds(Integer[] addUserIds) {
        this.addUserIds = addUserIds;
    }

    public List getAddUserLabels() {
        return addUserLabels;
    }

    public void setAddUserLabels(List addUserLabels) {
        this.addUserLabels = addUserLabels;
    }

    public List getRemoveUserLabels() {
        return removeUserLabels;
    }

    public void setRemoveUserLabels(List removeUserLabels) {
        this.removeUserLabels = removeUserLabels;
    }

    public Integer[] getSelectedAddUserIds() {
        return selectedAddUserIds;
    }

    public void setSelectedAddUserIds(Integer[] selectedAddUserIds) {
        this.selectedAddUserIds = selectedAddUserIds;
    }

    public Integer[] getSelectedRemoveUserIds() {
        return selectedRemoveUserIds;
    }

    public void setSelectedRemoveUserIds(Integer[] selectedRemoveUserIds) {
        this.selectedRemoveUserIds = selectedRemoveUserIds;
    }

	public VKCCategory getCategory() throws DBException {
		if (category == null) {
			category = VKCCategorySerializer.retrieveCategory(getCategoryId());
		}
		
		return category;
	}

	public VKCDocument getDocument() throws DBException {
		if (document == null) {
			document = VKCDocumentSerializer.retrieveDocument(getDocumentId());
		}
		
		return document;
	}
	
	public boolean isRegisterCategory() {
		if (getCategoryId() != null && getCategoryId().intValue() > 0 && (getDocumentId() == null || getDocumentId().intValue() <= 0)) {
			return true;
		}
		
		return false;
	}

	public boolean isRegisterDocument() {
		if (getCategoryId() != null && getCategoryId().intValue() > 0 && getDocumentId() != null && getDocumentId().intValue() > 0) {
			return true;
		}
		
		return false;
	}
}