/*
 * $Id: FunctionalViewForm.java,v 1.1 2006/10/04 03:15:14 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: FunctionalViewForm.java,v $
 * Revision 1.1  2006/10/04 03:15:14  marbobo
 * + Vollständige Unterstützung für Templates implementiert
 * + Alles von Virtoweb auf ProCoBa umgestellt
 *
 * Revision 1.21  2006/07/26 11:38:52  marbobo
 * + Document-Lock eingebaut
 *
 * Revision 1.20  2006/07/10 11:24:59  marbobo
 * + Bugfix
 *
 * Revision 1.19  2006/07/05 21:00:08  marbobo
 * + History-Funktionalität für Projekt- und Funktionssicht-Tabs implementiert
 *
 * Revision 1.18  2005/09/15 13:42:58  marbobo
 * + Sprachabhängige Sortierung implementiert
 *
 * Revision 1.17  2005/09/07 13:51:02  marbobo
 * + Sortierung nach Erstellungsdatum implementiert
 *
 * Revision 1.16  2005/03/21 20:28:08  marbobo
 * + DocSize auf Type Long umgestellt
 *
 * Revision 1.15  2004/11/09 14:35:41  marbobo
 * + Umstellung von authorId auf publisherId
 * + Hinzufügen von AuthorName für Dokumente
 * + Nötwendige Änderungen betreffend AuthorName und PublisherId
 *
 * Revision 1.14  2004/10/31 03:04:25  marbobo
 * + Verbesserungen und Bugfixes
 *
 * Revision 1.13  2004/07/20 15:22:23  jonyp
 * added some functionality to display dialog in mainframe or popup-window
 *
 * Revision 1.12  2004/06/27 17:41:15  marbobo
 * + Quellcode maintenance
 *
 * Revision 1.11  2004/06/24 21:17:58  marbobo
 * + Unterkategorien sortieren
 *
 * Revision 1.10  2004/06/21 10:51:52  marbobo
 * + Lesbare-Kategorien anzeigen
 *
 * Revision 1.9  2004/06/14 16:33:50  jonyp
 * added functionality for delete subfolders
 *
 * Revision 1.8  2004/06/02 22:30:08  marbobo
 * + Sortierungsfunktion für Dokumente
 *
 * Revision 1.7  2004/05/25 21:02:49  marbobo
 * + Kategorie- und Dokumentfunktionen hinzugefügt
 *
 * Revision 1.6  2004/05/21 16:44:36  jonyp
 * change static text "Parent category" to dynmaically written name of parent category name
 *
 * Revision 1.5  2004/04/27 19:47:24  marbobo
 * + Dokumentsicht erweitert (mit/ohne Details)
 *
 * Revision 1.4  2004/04/08 09:44:52  jonyp
 * *** empty log message ***
 *  
 */

package vkc.procoba.function;

import org.apache.struts.action.ActionMapping;

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.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCDocument;
import vkc.db.entities.VKCEntity;
import vkc.db.entities.VKCSubCategory;
import vkc.db.serializer.VKCCategorySerializer;
import vkc.util.VKCCategoryPathNode;
import vkc.util.VKCStringUtils;
import vkc.exception.DBException;
import vkc.view.form.BasicActionForm;
import vkc.view.PageId;

public class FunctionalViewForm extends BasicActionForm {
	public final static int CATEGORY_SORT_NAME_UP   		= 1;
	public final static int CATEGORY_SORT_NAME_DOWN 		= 2;

	public final static int DOCUMENT_SORT_PUBLISHING_DATE_UP   	= 1;
	public final static int DOCUMENT_SORT_PUBLISHING_DATE_DOWN 	= 2;

	public final static int DOCUMENT_SORT_TITLE_UP  			= 3;
	public final static int DOCUMENT_SORT_TITLE_DOWN			= 4;

	public final static int DOCUMENT_SORT_AUTHOR_UP 			= 5;
	public final static int DOCUMENT_SORT_AUTHOR_DOWN			= 6;
	
	public final static int DOCUMENT_SORT_SIZE_UP  				= 7;
	public final static int DOCUMENT_SORT_SIZE_DOWN 			= 8;

	public final static int DOCUMENT_SORT_TYPE_UP  				= 9;
	public final static int DOCUMENT_SORT_TYPE_DOWN 			= 10;

	public final static int DOCUMENT_SORT_PUBLISHER_UP 			= 13;
	public final static int DOCUMENT_SORT_PUBLISHER_DOWN		= 14;

	public final static int DOCUMENT_SORT_CREATION_DATE_UP   	= 15;
	public final static int DOCUMENT_SORT_CREATION_DATE_DOWN 	= 16;

	protected Integer categorySortMode 	= new Integer(CATEGORY_SORT_NAME_UP);
	protected Integer documentSortMode 	= new Integer(DOCUMENT_SORT_PUBLISHING_DATE_DOWN);
	protected Integer functionalViewId 	= VKCEntity.ID_UNDEFINED;
	protected Integer selectedId 		= null;
	protected Integer subfolderId 		= VKCEntity.ID_UNDEFINED;

	protected Integer[] showDocumentDetails = new Integer[0];

	protected List accessibleSubCategories 		= null;
	
	protected VKCCategory category 	= null;
	protected VKCCategory subfolder = null;

	public void reset(ActionMapping mapping, HttpServletRequest request) {
		super.reset(mapping, request);

		categorySortMode 	= new Integer(CATEGORY_SORT_NAME_UP);
		documentSortMode 	= new Integer(DOCUMENT_SORT_PUBLISHING_DATE_DOWN);
		functionalViewId 	= VKCEntity.ID_UNDEFINED;
		selectedId 			= null;
		subfolderId 		= VKCEntity.ID_UNDEFINED;

		showDocumentDetails = new Integer[0];

		accessibleSubCategories   = null;
		
		category  = null;
		subfolder = null;
	}

	public Integer getSubfolderId() {
		return subfolderId;
	}

	public void setSubfolderId( Integer i ) {
		subfolderId = i;
		category = null;
	}

	public VKCCategory getCategory() throws DBException {
		if (category == null) {
			category = VKCCategorySerializer.retrieveCategory(getSubfolderId());
			
			if (category != null) {
				if (category.getFlag().equals(VKCCategory.FLAG_DELETED)) {
					category = null;
				}
			}
		}
		
		return category;
	}
	
	public List getAllRealFunctionalViewDocuments() throws DBException {
        return getCategory().getDocuments();
	}
	
	public List getAllVirtualFunctionalViewDocuments() throws DBException {
		return getCategory().getVirtualDocuments(getUser());
	}
	
	public List getAllFunctionalViewDocuments() throws DBException {
		
	     List allDocs = new ArrayList();
	     
	     // get all real documents
	     allDocs.addAll(getCategory().getDocuments());
	     
	     // get all virtual documents
	     allDocs.addAll(getCategory().getVirtualDocuments(getUser()));
	     
	     documentSort(allDocs, getDocumentSortMode());
	     
	     return allDocs;
	}
	
	public List getCurrentFunctionalViewPath() throws DBException {
		if (getCategory() != null) {
			List path = getCategory().getAbsPathDescr().getPathNodes();
	
			for (Iterator iter = path.iterator(); iter.hasNext();) {
				VKCCategoryPathNode node = (VKCCategoryPathNode)iter.next();
		
				if (node.getPathId().equals(getFunctionalViewId())) {
					break;
				}

				iter.remove();
			}
		
			return path;
		}

		return new ArrayList();
	}
	
	public Integer getFunctionalViewId() {
		return functionalViewId;
	}

	public void setFunctionalViewId(Integer i) {
		functionalViewId = i;
	}

	public String getFunctionalViewFolderViewLink() {
			return "/functionalView.do?functionalViewId=" + getFunctionalViewId();
	}

    public Integer getParentCategoryId() throws DBException {
        return getCategory().getParentCategoryId();	
    }
	
	public boolean isFunctionalViewRootCategory() {
	    if (getFunctionalViewId().equals(getSubfolderId())) {
	    	return true;
	    } 

	    return false;
	}

	public Integer[] getShowDocumentDetails() {
		return showDocumentDetails;
	}

	public void setShowDocumentDetails(Integer[] list) {
		showDocumentDetails = list;
	}

	public boolean getShowDocDetails(int i) {
		List ids = Arrays.asList(getShowDocumentDetails());
		
		return ids.contains(new Integer(i));
	}

	public Integer getSelectedId() {
		return selectedId;
	}

	public void setSelectedId(Integer i) {
		selectedId = i;
	}

	public String getNewDocumentLink() {
		return "/newDocument.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
			"&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId() + 
			"&categoryId=" + getSubfolderId();
	}

	public String getNewDocumentVersionLink() {
		return "/newDocumentVersion.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
		    "&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId(); 
	}

	public String getShowDocumentVersionsLink() {
		return "/showDocumentVersions.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
			"&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId(); 
	}

	public String getCreateCategoryLink() {
		return "/createCategory.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
			"&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId() + 
			"&parentCategoryId=" + getSubfolderId() +
			"&validate=false" +
			"&copyParentAcl=true";
	}

	public String getDeleteCategoryLink() {
		return "/functionalView.do?" + 
			   "&functionalViewId=" + getFunctionalViewId() +
			   "&subfolderId=" + getSubfolderId() + 
			   "&action.delete.subfolder=true";			
	}

	public String getEditCategoryLink() {
		return "/editCategory.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
			"&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId() + 
			"&categoryId=" + getSubfolderId() +
			"&validate=false";
	}
	
	public String getEditAclLink() {
		return "/editCategoryAcl.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
			"&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId() + 
			"&categoryId=" + getSubfolderId() +
			"&init=true";
	}

	public String getDisplayAclLink() {
		return "/displayAcl.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
			"&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId() + 
			"&categoryId=" + getSubfolderId() +
			"&init=true&ownWindow=false";
	}

	public String getEditDocumentLink() {
		return "/editDocument.do" + 
			"?sourcePageId=" + PageId.FUNCTIONAL_VIEW +
			"&targetId=" + getFunctionalViewId() + 
			"&subTargetId=" + getSubfolderId() + 
			"&categoryId=" + getSubfolderId() +
			"&init=true";
	}

	public Integer getCategorySortMode() {
		return categorySortMode;
	}

	public void setCategorySortMode(Integer i) {
		categorySortMode = i;
	}
	
	public Integer getDocumentSortMode() {
		return documentSortMode;
	}

	public void setDocumentSortMode(Integer i) {
		documentSortMode = i;
	}

	private void categorySort(List categories, Integer sortMode) {
		int mode = sortMode.intValue();

		Comparator c = null;
		final Collator collator = Collator.getInstance(getUser().getLanguage().getLocale());

		if (mode == CATEGORY_SORT_NAME_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCSubCategory s1 = (VKCSubCategory)o1;
					VKCSubCategory s2 = (VKCSubCategory)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(s1.getName()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(s2.getName()));
                	
                	return key1.compareTo(key2);
				}
			};
		} else if (mode == CATEGORY_SORT_NAME_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCSubCategory s1 = (VKCSubCategory)o1;
					VKCSubCategory s2 = (VKCSubCategory)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(s1.getName()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(s2.getName()));
                	
                	return key2.compareTo(key1);
				}
			};
		}
		
		Collections.sort(categories, c);		
	}

	private void documentSort(List documents, Integer sortMode) {
		int mode = sortMode.intValue();

		Comparator c = null;
		final Collator collator = Collator.getInstance(getUser().getLanguage().getLocale());

		if (mode == DOCUMENT_SORT_PUBLISHING_DATE_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
					return d1.getPublished().after(d2.getPublished()) ? 1 : 0;
				}
			};
		} else if (mode == DOCUMENT_SORT_PUBLISHING_DATE_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
					return d1.getPublished().before(d2.getPublished()) ? 1 : 0;
				}
			};
		} else if (mode == DOCUMENT_SORT_CREATION_DATE_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
					if (d1.getCreationDate() != null && d2.getCreationDate() != null) {
						return d1.getCreationDate().after(d2.getCreationDate()) ? 1 : 0;
					}
					
					return -1;
				}
			};
		} else if (mode == DOCUMENT_SORT_CREATION_DATE_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
					if (d1.getCreationDate() != null && d2.getCreationDate() != null) {
						return d1.getCreationDate().before(d2.getCreationDate()) ? 1 : 0;
					}
					
					return -1;
				}
			};
		} else if (mode == DOCUMENT_SORT_TITLE_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getTitle()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getTitle()));
                	
                	return key1.compareTo(key2);
				}
			};
		} else if (mode == DOCUMENT_SORT_TITLE_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getTitle()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getTitle()));
                	
                	return key2.compareTo(key1);
				}
			};
		} else if (mode == DOCUMENT_SORT_AUTHOR_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getAuthorName()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getAuthorName()));
                	
                	return key1.compareTo(key2);
				}
			};
		} else if (mode == DOCUMENT_SORT_AUTHOR_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getAuthorName()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getAuthorName()));
                	
                	return key2.compareTo(key1);
				}
			};
		} else if (mode == DOCUMENT_SORT_PUBLISHER_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getPublisherName()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getPublisherName()));
                	
                	return key1.compareTo(key2);
				}
			};
		} else if (mode == DOCUMENT_SORT_PUBLISHER_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getPublisherName()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getPublisherName()));
                	
                	return key2.compareTo(key1);
				}
			};
		} else if (mode == DOCUMENT_SORT_SIZE_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
					return d1.getDocSize().longValue() > d2.getDocSize().longValue() ? 1 : 0;
				}
			};
		} else if (mode == DOCUMENT_SORT_SIZE_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
					return d1.getDocSize().longValue() < d2.getDocSize().longValue() ? 1 : 0;
				}
			};
		} else if (mode == DOCUMENT_SORT_TYPE_UP) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getDocumentType().getExtension()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getDocumentType().getExtension()));
                	
                	return key1.compareTo(key2);
				}
			};
		} else if (mode == DOCUMENT_SORT_TYPE_DOWN) {
			c = new Comparator() {
				public int compare(Object o1, Object o2) {
					VKCDocument d1 = (VKCDocument)o1;
					VKCDocument d2 = (VKCDocument)o2;
					
                	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getDocumentType().getExtension()));
                	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getDocumentType().getExtension()));
                	
                	return key2.compareTo(key1);
				}
			};
		}
		
		Collections.sort(documents, c);
	}

	public boolean getHasDocuments() throws DBException {
		return !getAllFunctionalViewDocuments().isEmpty();
	}

	public List getAccessibleSubCategories() throws DBException {
		if (accessibleSubCategories == null) {
			if (getCategory() == null) {
				accessibleSubCategories = new ArrayList();
			} else {
				accessibleSubCategories = getCategory().getAccessibleSubCategories(getUser());
				categorySort(accessibleSubCategories, getCategorySortMode());
			}
		}
		
		return accessibleSubCategories;
	}
    
    public String getLockUserInfo(String documentId) {
        String lockUser = vkc.webdav.WebDavServlet.getLockUserName(new Integer(documentId));
        
        if (lockUser != null) {
            return getResources().getMessage(getLocale(), "vkc.string.lockUserInfo", lockUser);
        }
        
        return "";
    }
}