/*
 * File   : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.documentcenter/src/com/alkacon/opencms/documentcenter/CmsDocumentFrontend.java,v $
 * Date   : $Date: 2010/03/19 15:31:13 $
 * Version: $Revision: 1.3 $
 *
 * This file is part of the Alkacon OpenCms Add-On Module Package
 *
 * Copyright (c) 2010 Alkacon Software GmbH (http://www.alkacon.com)
 *
 * The Alkacon OpenCms Add-On Module Package is free software: 
 * you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * The Alkacon OpenCms Add-On Module Package 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 the Alkacon OpenCms Add-On Module Package.  
 * If not, see http://www.gnu.org/licenses/.
 *
 * For further information about Alkacon Software GmbH, please see the
 * company website: http://www.alkacon.com.
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org.
 */
package com.alkacon.opencms.v8.documentcenter;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.i18n.CmsMessages;
import org.opencms.jsp.CmsJspActionElement;
import org.opencms.jsp.CmsJspNavElement;
import org.opencms.util.CmsStringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
/**
 * Provides customized methods for the document center frontend output.<p>
 * 
 * @author Andreas Zahner
 * 
 * @version $Revision: 1.3 $ 
 * 
 * @since 6.2.1
 */
/**
 *
 */
public class CmsDocumentFrontend extends CmsJspActionElement {
    /** Request attribute that stores if a disclaimer should be shown. */
    public static final String ATTR_DISCLAIMER = "oamp_doccenter_disclaimer";
    /** Request attribute that stores the absolute path to the current document center folder. */
    public static final String ATTR_FULLPATH = "oamp_doccenter_fullpath";
    /** Request attribute that stores the relative path to the current document center folder. */
    public static final String ATTR_PATHPART = "oamp_doccenter_pathpart";
    /** Request attribute that stores the absolute path to the document center start folder. */
    public static final String ATTR_STARTPATH = "oamp_doccenter_startpath";
    /** Name of the column: date created. */
    public static final String COLUMN_NAME_DATECREATED = "datecreated";
    /** Name of the column: date modified. */
    public static final String COLUMN_NAME_DATEMODIFIED = "datemodified";
    /** Name of the column: document folder. */
    public static final String COLUMN_NAME_FOLDER = "folder";
    /** Name of the column: document id. */
    public static final String COLUMN_NAME_ID = "id";
    /** Name of the column: document languages. */
    public static final String COLUMN_NAME_LANGUAGE = "lang";
    /** Name of the column: document size. */
    public static final String COLUMN_NAME_SIZE = "size";
    /** Name of the column: document title. */
    public static final String COLUMN_NAME_TITLE = "title";
    /** Name of the column: document type. */
    public static final String COLUMN_NAME_TYPE = "type";
    /** The sortable column default sort directions, must correspond to the sortable columns {@link #COLUMNS_SORTABLE}. */
    public static final String[] COLUMNS_DIRECTIONS = {
        CmsDocument.SORT_DIRECTION_ASC,
        CmsDocument.SORT_DIRECTION_ASC,
        CmsDocument.SORT_DIRECTION_ASC,
        CmsDocument.SORT_DIRECTION_DESC,
        CmsDocument.SORT_DIRECTION_DESC,
        CmsDocument.SORT_DIRECTION_DESC};
    /** The sortable column default sort directions as list. */
    public static final List<String> COLUMNS_DIRECTIONS_LIST = Arrays.asList(COLUMNS_DIRECTIONS);
    /** Stores the column names that are sortable. */
    public static final String[] COLUMNS_SORTABLE = {
        COLUMN_NAME_TYPE,
        COLUMN_NAME_ID,
        COLUMN_NAME_TITLE,
        COLUMN_NAME_SIZE,
        COLUMN_NAME_DATEMODIFIED,
        COLUMN_NAME_DATECREATED};
    /** The column names that are sortable as list. */
    public static final List<String> COLUMNS_SORTABLE_LIST = Arrays.asList(COLUMNS_SORTABLE);
    /** Name of the file extensions of the icons of the document list. */
    public static final String ICON_POSTFIX = ".gif";
    /** Page type: default (shows the document list). */
    public static final String PAGE_TYPE_DEFAULT = "default";
    /** Request parameter name for the sort column parameter. */
    public static final String PARAM_SORT_COLUMN = "sortcol";
    /** Request parameter name for the sort direction parameter. */
    public static final String PARAM_SORT_DIRECTION = "sortdir";
    /** Property name to look if the document id column is shown. */
    public static final String PROPERTY_COLUMN_ID = "docs.columnid";
    /** Property name to look for document list column names to hide. */
    public static final String PROPERTY_COLUMNS_HIDE = "docs.hidecolumns";
    /** Property name to look for document list date columns to hide (old way, used for compatibility reasons). */
    public static final String PROPERTY_COLUMNS_HIDE_DATE = "categoryDateCreated";
    /** Property name to determine if the document center should consider attachments of the documents. */
    public static final String PROPERTY_USE_ATTACHMENTS = "docs.useattachments";
    /** Property name to set the default type if using different types. */
    public static final String PROPERTY_USE_DEFAULTTYPE = "docs.defaulttype";
    /** Property name to determine if the document center should consider language versions of the documents. */
    public static final String PROPERTY_USE_LANGUAGES = "docs.uselanguages";
    /** Property name to determine if the document center should consider different types of the documents. */
    public static final String PROPERTY_USE_TYPES = "docs.usetypes";
    /** The property values of the sort methods, must be in the same order as {@link #COLUMNS_SORTABLE}. */
    public static final String[] SORT_METHODS = {
        CmsDocument.SORT_METHOD_TYPE,
        CmsDocument.SORT_METHOD_BY_ID,
        CmsDocument.SORT_METHOD_ALPHABETICAL,
        CmsDocument.SORT_METHOD_SIZE,
        CmsDocument.SORT_METHOD_BY_DATEMODIFIED,
        CmsDocument.SORT_METHOD_BY_DATECREATED};
    /** The property values of the sort methods as list. */
    public static final List<String> SORT_METHODS_LIST = Arrays.asList(SORT_METHODS);
    /** The extension of the default type if using different types of documents. */
    private String m_defaultType;
    /** The page type to show. */
    private String m_pageType;
    /** The parameter of the sort column. */
    private String m_paramSortColumn;
    /** The parameter of the sort direction. */
    private String m_paramSortDirection;
    /** The value of the sort method property ("method:direction:includefolders"). */
    private String m_sortMethod;
    /** Determines if attachments of documents are present. */
    private Boolean m_useAttachments;
    /** Determines if language versions of documents are present. */
    private Boolean m_useLanguages;
    /** Determines if different types of documents are present. */
    private Boolean m_useTypes;
    /**
     * Empty constructor, required for every JavaBean.
     */
    public CmsDocumentFrontend() {
        super();
    }
    /**
     * Constructor, with parameters.
     * 
     * @param context the JSP page context object
     * @param req the JSP request 
     * @param res the JSP response 
     */
    public CmsDocumentFrontend(PageContext context, HttpServletRequest req, HttpServletResponse res) {
        super(context, req, res);
        // TODO: fix all current uri references to use proper sitepath
    }
    /**
     * Creates the HTML code for the default breadcrumb navigation without the "up one folder" icon.<p>
     * 
     * Used by: elements/navigation.jsp.<p>
     * 
     * @param startFolder the start folder to build the navigation from
     * @param navList the navigation elements (CmsJspNavElement)
     * @param anchorClass the CSS class which will be used for the anchors
     * @param separator the separator which will be used to separate the entries
     * @param sepBeforeFirst if true, separator will be displayed before first element, too
     * @return the HTML code for the breadcrumb navigation
     */
    public String buildBreadCrumbNavigation(
        String startFolder,
        List<CmsJspNavElement> navList,
        String anchorClass,
        String separator,
        boolean sepBeforeFirst) {
        StringBuffer result = new StringBuffer(64);
        boolean isFirst = true;
        if (sepBeforeFirst) {
            isFirst = false;
        }
        String locNavText = CmsPropertyDefinition.PROPERTY_NAVTEXT + "_" + getRequestContext().getLocale().toString();
        String locTitle = CmsPropertyDefinition.PROPERTY_TITLE + "_" + getRequestContext().getLocale().toString();
        String currFolder = (String)getRequest().getAttribute(ATTR_FULLPATH);
        // create the navigation 
        Iterator<CmsJspNavElement> i = navList.iterator();
        while (i.hasNext()) {
            CmsJspNavElement navElement = i.next();
            String navText = navElement.getProperties().get(locNavText);
            if (CmsStringUtil.isEmptyOrWhitespaceOnly(navText)) {
                navText = navElement.getNavText();
            }
            if (navElement.getResourceName().startsWith(startFolder)) {
                // check the navigation text
                if (navText.indexOf("??? NavText") != -1) {
                    navText = navElement.getProperties().get(locTitle);
                    if (CmsStringUtil.isEmptyOrWhitespaceOnly(navText)) {
                        navText = navElement.getTitle();
                    }
                    if (CmsStringUtil.isEmptyOrWhitespaceOnly(navText)) {
                        navText = navElement.getFileName();
                    }
                    if (navText.endsWith("/")) {
                        navText = navText.substring(0, (navText.length() - 1));
                    }
                }
                // don't show separator in front of first element
                if (!isFirst) {
                    result.append(separator);
                } else {
                    isFirst = false;
                }
                if (navElement.getResourceName().equals(currFolder) && (navList.size() > 1)) {
                    // the current folder will not be linked
                    result.append("<span class=\"");
                    result.append(anchorClass);
                    result.append("\">");
                    result.append(navText);
                    result.append("</span>");
                } else {
                    // create the link to the folder
                    result.append("<a href=\"");
                    result.append(CmsDocumentFactory.getLink(this, navElement.getResourceName()));
                    result.append("\" class=\"");
                    result.append(anchorClass);
                    result.append("\">");
                    result.append(navText);
                    result.append("</a>");
                }
            }
        }
        return result.toString();
    }
    /**
     * Creates the HTML code for the document or resource icon in document list, version list and search result list.<p>
     * 
     * Used by: jsptemplates/list_documents.txt, elements/docversions.jsp, pages/jsp_pages/page_search_code.jsp.<p>
     * 
     * @param docName the resource name of the document
     * @param messages the localized messages
     * @param resourcePath the path to the images
     * @param isFolder true if the document is a folder, otherwise false
     * @return the HTML code for the document icon
     */
    public String buildDocIcon(String docName, CmsMessages messages, String resourcePath, boolean isFolder) {
        return buildDocIcon(docName, messages, resourcePath, isFolder, 16, 16);
    }
    /**
     * Creates the HTML code for the document or resource icon in document list, version list and search result list.<p>
     * 
     * Used by: jsptemplates/list_documents.txt, elements/docversions.jsp, pages/jsp_pages/page_search_code.jsp.<p>
     * 
     * @param docName the resource name of the document
     * @param messages the localized messages
     * @param resourcePath the path to the images
     * @param isFolder true if the document is a folder, otherwise false
     * @param imgWidth the width of the icon image
     * @param imgHeight the height of the icon image
     * @return the HTML code for the document icon
     */
    public String buildDocIcon(
        String docName,
        CmsMessages messages,
        String resourcePath,
        boolean isFolder,
        int imgWidth,
        int imgHeight) {
        String iconSrc, iconTitle, iconAlt;
        // folder
        if (isFolder) {
            iconSrc = "ic_folder";
            iconTitle = messages.key("documentlist.icon.folder.title");
            iconAlt = messages.key("documentlist.icon.folder.alt");
        }
        // file
        else {
            String postfix = CmsDocument.getPostfix(docName);
            postfix = CmsDocument.getPostfixAdjusted(postfix);
            iconSrc = "ic_app_" + postfix;
            iconTitle = messages.keyDefault("documentlist.icon.file.title." + postfix, "");
            iconAlt = messages.keyDefault("documentlist.icon.file.alt." + postfix, "");
            if ((postfix.equals("")) || (!getCmsObject().existsResource(resourcePath + iconSrc + ICON_POSTFIX))) {
                iconSrc = "ic_app_unknown";
                iconTitle = messages.key("documentlist.icon.file.title.unknown");
                iconAlt = messages.key("documentlist.icon.file.alt.unknown");
            }
        }
        StringBuffer result = new StringBuffer(256);
        result.append("<img src=\"");
        result.append(link(resourcePath + iconSrc + ICON_POSTFIX));
        result.append("\" width=\"").append(imgWidth).append("\" height=\"").append(imgHeight);
        result.append("\" border=\"0\" alt=\"");
        result.append(iconAlt);
        result.append("\" title=\"");
        result.append(iconTitle);
        result.append("\"/>");
        return result.toString();
    }
    /**
     * Returns the column header including the link to sort the list by the column criteria.<p>
     * 
     * @param columnName the internal column name
     * @param resourcePath the path to the image resources
     * @param messages the initialized localized messages to use
     * @return the column header including the link to sort the list by the column criteria
     */
    public String getColumnHeader(String columnName, String resourcePath, CmsMessages messages) {
        if (!isBeanSortInitialized()) {
            initSort();
        }
        if (m_pageType.equals("default") && COLUMNS_SORTABLE_LIST.contains(columnName)) {
            // column is sortable and we are on a default page, so columns are sortable
            StringBuffer result = new StringBuffer(256);
            String dir = m_paramSortDirection;
            String newDir = dir;
            boolean isCurrentColumn = false;
            if (columnName.equals(m_paramSortColumn)) {
                // the column is the current sort column
                isCurrentColumn = true;
                // switch new sort direction link for current sort column
                if ((dir != null) && dir.equals(CmsDocument.SORT_DIRECTION_ASC)) {
                    newDir = CmsDocument.SORT_DIRECTION_DESC;
                } else {
                    newDir = CmsDocument.SORT_DIRECTION_ASC;
                }
            } else {
                // use default sort direction for other columns
                newDir = COLUMNS_DIRECTIONS_LIST.get(COLUMNS_SORTABLE_LIST.indexOf(columnName));
            }
            // create the link for sorting the column
            StringBuffer link = new StringBuffer(128);
            link.append((String)getRequest().getAttribute(ATTR_FULLPATH));
            link.append("?").append(PARAM_SORT_COLUMN).append("=").append(columnName);
            link.append("&amp;").append(PARAM_SORT_DIRECTION).append("=").append(newDir);
            // set the title for the headline
            String sortTitle = messages.key(
                "documentlist.sort." + newDir,
                messages.key("documentlist.headline." + columnName));
            result.append("<a href=\"");
            result.append(CmsDocumentFactory.getLink(this, link.toString()));
            result.append("\" class=\"docshead\" title=\"");
            result.append(sortTitle);
            result.append("\">");
            result.append(messages.key("documentlist.headline." + columnName));
            if (isCurrentColumn) {
                // set the marker icon for the current sort column
                result.append("&nbsp;");
                result.append("<img src=\"");
                result.append(resourcePath).append("ic_sort_").append(dir).append(".png");
                result.append("\" border=\"0\" alt=\"");
                result.append(sortTitle);
                result.append("\" title=\"");
                result.append(sortTitle);
                result.append("\"/>");
            }
            result.append("</a>");
            return result.toString();
        } else {
            // column is not sortable, simply print localized headline
            return messages.key("documentlist.headline." + columnName);
        }
    }
    /**
     * Returns the defaultType.<p>
     *
     * @return the defaultType
     */
    public String getDefaultType() {
        return m_defaultType;
    }
    /**
     * Collects the names of the columns to hide in the document list view.<p>
     * 
     * Columns that can be hidden are: date created, date last modified, document id.<p>
     * 
     * @return the names of the clumns to hide
     */
    public List<String> getHiddenColumns() {
        List<String> result = new ArrayList<String>(4);
        String ignoredCols = property(PROPERTY_COLUMNS_HIDE, "search", "");
        result = CmsStringUtil.splitAsList(ignoredCols, ';');
        // backward compatibility: check for property defining visibility of date columns
        String showDateData = property("categoryDateCreated", "search", "");


Answer:         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(showDateData)) {