/*
 * $Id: ConversionsMaintenanceForm.java,v 1.7 2007/08/27 08:49:19 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 * 
 * Created on 04.11.2004
 *
 * $Log: ConversionsMaintenanceForm.java,v $
 * Revision 1.7  2007/08/27 08:49:19  marbobo
 * + Kontext korrekt setzen
 *
 * Revision 1.6  2006/07/13 23:16:00  marbobo
 * + Dokumentformate sortiert
 *
 * Revision 1.5  2005/09/15 13:39:06  marbobo
 * + Sprachabhängige Sortierung implementiert
 *
 * Revision 1.4  2004/12/17 00:55:34  koppy
 * Checkboxen statt Radio-Buttons
 *
 * Revision 1.3  2004/11/12 00:19:57  marbobo
 * - Unnötige Import-Anweisungen entfernt
 *
 * Revision 1.2  2004/11/10 15:02:48  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.1  2004/11/08 12:28:13  koppy
 * initiale version
 *
 */
package vkc.administration.form;

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

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionMapping;

import vkc.db.common.ConversionStatus;
import vkc.db.serializer.VKCDocumentTypeSerializer;
import vkc.exception.DBException;
import vkc.misc.VKCLogManager;
import vkc.util.VKCStringUtils;
import vkc.util.sort.DocumentTypeSortFactory;

/**
 * This class represents
 * 
 * @author Andreas Koop
 */
public class ConversionsMaintenanceForm extends SystemMaintenanceForm {
    public static final int SORT_DOCUMENT_UP = 0;

    public static final int SORT_DOCUMENT_DOWN = 1;

    public static final int SORT_STATUS_UP = 2;

    public static final int SORT_STATUS_DOWN = 3;

    public static final int SORT_STARTED_UP = 4;

    public static final int SORT_STARTED_DOWN = 5;

    public static final int SORT_REITERATIONS_UP = 6;

    public static final int SORT_REITERATIONS_DOWN = 7;

    public static final int SORT_REMARK_UP = 8;

    public static final int SORT_REMARK_DOWN = 9;

    private List conversions = new ArrayList();

    private List convertibleDocTypes = new ArrayList();

    private Integer[] selectedDocTypeIds = new Integer[0];

    private Integer[] selectedIds = new Integer[0];

    private String selectedCmdAction = "noaction";

    private int sortMode = SORT_DOCUMENT_UP;

    private int listIndex = 0;

    private int entriesPerPage = 10;

    private List comparators = null;

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

        try {
            this.conversions = ConversionStatus.getAllConversionStatus();
            this.convertibleDocTypes = VKCDocumentTypeSerializer.getConvertibleDocumentTypes();
            setSelectedContext(CONVERSIONS);
        } catch (DBException e) {
            VKCLogManager.errorLog(this, "", "Configuration of converter servers could not be loaded from DB", e);
        }
    }

    /**
     * ConversionsMaintenanceForm()
     */
    public List getComparators() {
        if (comparators == null) {
            comparators = new ArrayList();
            final Collator collator = Collator.getInstance(getUser().getLanguage().getLocale());

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getDocumentName()));
                    CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getDocumentName()));

                    return key1.compareTo(key2);
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getDocumentName()));
                    CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getDocumentName()));

                    return key2.compareTo(key1);
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getStatus()));
                    CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getStatus()));

                    return key1.compareTo(key2);
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getStatus()));
                    CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getStatus()));

                    return key2.compareTo(key1);
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    if (c1.getStarted() == null) {
                        if (c2.getStarted() == null) {
                            return 0;
                        }

                        return -1;
                    }

                    if (c2.getStarted() == null) {
                        return 1;
                    }

                    if (c1.getStarted().before(c2.getStarted())) {
                        return -1;
                    } else if (c1.getStarted().after(c2.getStarted())) {
                        return 1;
                    }

                    return 0;
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    if (c1.getStarted() == null) {
                        if (c2.getStarted() == null) {
                            return 0;
                        }

                        return 1;
                    }

                    if (c2.getStarted() == null) {
                        return -1;
                    }

                    if (c1.getStarted().before(c2.getStarted())) {
                        return 1;
                    } else if (c1.getStarted().after(c2.getStarted())) {
                        return -1;
                    }

                    return 0;
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    if (c1.getReiterations() < c2.getReiterations()) {
                        return -1;
                    } else if (c1.getReiterations() > c2.getReiterations()) {
                        return 1;
                    }

                    return 0;
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    if (c1.getReiterations() < c2.getReiterations()) {
                        return 1;
                    } else if (c1.getReiterations() > c2.getReiterations()) {
                        return -1;
                    }

                    return 0;
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getComment()));
                    CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getComment()));

                    return key1.compareTo(key2);
                }
            });

            comparators.add(new Comparator() {
                public int compare(Object o1, Object o2) {
                    ConversionStatus c1 = (ConversionStatus) o1;
                    ConversionStatus c2 = (ConversionStatus) o2;

                    CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getComment()));
                    CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getComment()));

                    return key2.compareTo(key1);
                }
            });
        }

        return comparators;
    }

    /**
     * Gibt eine Liste aller Konvertierungsstatus zurück.
     * 
     * @return Listen von ConversionStatus-Objekten
     */
    public List getConversions() {
        Collections.sort(conversions, (Comparator) getComparators().get(this.getSortMode()));

        return conversions;
    }

    public List getVisibleConversions() {
        if (conversions.isEmpty()) {
            return new ArrayList();
        }

        int length = entriesPerPage;
        int convSize = conversions.size();

        if (listIndex + entriesPerPage > convSize) {
            length = convSize % entriesPerPage;
        }

        if (listIndex + length > convSize) {
            listIndex = 0;
        }

        List visible = new ArrayList();

        for (int i = listIndex; i < listIndex + length; i++) {
            visible.add(conversions.get(i));
        }

        return visible;
    }

    /**
     * Gibt alle konvertierbaren Dokumententypen zurück
     * 
     * @return
     */
    public List getConvertibleDocTypes() {
        DocumentTypeSortFactory.sort(convertibleDocTypes, DocumentTypeSortFactory.SORT_BY_EXTENSION_UP);

        return convertibleDocTypes;
    }

    /**
     * 
     * @return
     */
    public Integer[] getSelectedDocTypeIds() {
        return selectedDocTypeIds;
    }

    /**
     * 
     * @param selectedDocTypeId
     */
    public void setSelectedDocTypeIds(Integer[] selectedDocTypeIds) {
        this.selectedDocTypeIds = selectedDocTypeIds;
    }

    public Integer[] getSelectedIds() {
        return selectedIds;
    }

    public void setSelectedIds(Integer[] integers) {
        if (integers == null) {
            selectedIds = new Integer[0];
        } else {
            selectedIds = integers;
        }
    }

    public String getSelectedCmdAction() {
        return selectedCmdAction;
    }

    public void setSelectedCmdAction(String selectedCmdAction) {
        this.selectedCmdAction = selectedCmdAction;
    }

    public int getSortMode() {
        return sortMode;
    }

    public void setSortMode(int sortMode) {
        this.sortMode = sortMode;
    }

    public boolean isSortByDocument() {
        return this.sortMode == SORT_DOCUMENT_DOWN || this.sortMode == SORT_DOCUMENT_UP;
    }

    public boolean isSortByStatus() {
        return this.sortMode == SORT_STATUS_DOWN || this.sortMode == SORT_STATUS_UP;
    }

    public boolean isSortByStarted() {
        return this.sortMode == SORT_STARTED_DOWN || this.sortMode == SORT_STARTED_UP;
    }

    public boolean isSortByReiterations() {
        return this.sortMode == SORT_REITERATIONS_DOWN || this.sortMode == SORT_REITERATIONS_UP;
    }

    public boolean isSortByRemark() {
        return this.sortMode == SORT_REMARK_DOWN || this.sortMode == SORT_REMARK_UP;
    }

    public int getEntriesPerPage() {
        return entriesPerPage;
    }

    public void setEntriesPerPage(int entriesPerPage) {
        this.entriesPerPage = entriesPerPage;
    }

    public int getListIndex() {
        return listIndex;
    }

    public void setListIndex(int listIndex) {
        this.listIndex = listIndex;
    }

    public int getEntriesPageCount() {
        double pageCount = this.conversions.size();
        pageCount = pageCount / this.entriesPerPage;
        pageCount = Math.ceil(pageCount);

        return (int) pageCount;
    }

    public List getPageIndices() {
        ArrayList indices = new ArrayList();

        for (int i = 0; i < getEntriesPageCount(); i++) {
            indices.add(new Integer(i * entriesPerPage));
        }

        return indices;
    }
}