/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the
 * License at http://www.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.cms;

import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.util.Assert;
import com.arsdigita.mimetypes.MimeType;

import java.math.BigDecimal;

/**
 * Represents a mapping from (content section + content type) to a
 * template.  This class is is package scope since it is part of the
 * internal templating implementation.
 *
 * @author Stanislav Freidin (sfreidin@arsdigita.com)
 * @version $Id: //cms/dev/src/com/arsdigita/cms/SectionTemplateMapping.java#12 $
 */
public class SectionTemplateMapping extends TemplateMapping {

    public static final String versionId = "$Id: //cms/dev/src/com/arsdigita/cms/SectionTemplateMapping.java#12 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    public static final String BASE_DATA_OBJECT_TYPE =
        "com.arsdigita.cms.SectionTemplateMapping";

    public static final String SECTION      = "section";
    public static final String CONTENT_TYPE = "contentType";

    // Default constructor
    public SectionTemplateMapping() {
        this(BASE_DATA_OBJECT_TYPE);
    }

    // OID constructor
    public SectionTemplateMapping(OID oid) throws DataObjectNotFoundException {
        super(oid);
    }

    // ID constructor
    public SectionTemplateMapping(BigDecimal id) throws DataObjectNotFoundException {
        this(new OID(BASE_DATA_OBJECT_TYPE, id));
    }

    // DataObject constructor
    public SectionTemplateMapping(DataObject obj) {
        super(obj);
    }

    // Subtype constructor
    public SectionTemplateMapping(String type) {
        super(type);

        setDefault(Boolean.FALSE);
        setUseContext(TemplateManager.PUBLIC_CONTEXT);
    }

    public final ContentSection getContentSection() {
        return (ContentSection) DomainObjectFactory.newInstance
            ((DataObject)get(SECTION));
    }

    public final void setContentSection(ContentSection sec) {
        Assert.assertNotNull(sec);
        setAssociation(SECTION, sec);
    }

    public ACSObject getParent() {
        return getContentType();
    }

    public final ContentType getContentType() {
        return (ContentType) DomainObjectFactory.newInstance
            ((DataObject) get(CONTENT_TYPE));
    }

    public final void setContentType(ContentType t) {
        Assert.assertNotNull(t);
        setAssociation(CONTENT_TYPE, t);
    }

    /**
     * Determine if the template will be the default within its
     * context
     */
    public Boolean isDefault() {
        return (Boolean)get(IS_DEFAULT);
    }

    /**
     * Set whether the template will be the default within its
     * context
     */
    public void setDefault(Boolean b) {
        Assert.assertNotNull(b);
        set(IS_DEFAULT, b);
    }

    /**
     * Load the specified mapping; return null if no such mapping
     * exists
     * @deprecated use getMapping(ContentSection section, ContentType type, Template template, String useContext, MimeType mimeType)
     */
    protected static SectionTemplateMapping getMapping(ContentSection section, ContentType type,
                                                       Template template, String useContext
                                                       ) {
        return getMapping(section, type, template, useContext, 
                          MimeType.loadMimeType(Template.JSP_MIME_TYPE));
    }

    /**
     * Load the specified mapping; return null if no such mapping
     * exists
     */
    protected static SectionTemplateMapping getMapping
        (ContentSection section, ContentType type,
         Template template, String useContext, MimeType mimeType) {
        SectionTemplateCollection c = getTemplates(section, type, useContext);
        c.addEqualsFilter(TEMPLATE + "." + ACSObject.ID, template.getID());
        String mimeString = null;
        if (mimeType != null) {
            mimeString = mimeType.getMimeType();
        }
        if(!c.next()) return null;
        SectionTemplateMapping m = (SectionTemplateMapping)c.getDomainObject();
        Assert.assertTrue(!c.next());
        c.close();
        return m;
    }

    /**
     * Get the default template for the given use context and mime type
     */
    protected static Template getDefaultTemplate 
        (ContentSection section, ContentType type, String useContext, 
         MimeType mimeType) {
        SectionTemplateCollection c = 
            getDefaultTemplates(section, type, useContext);
        String mimeString = null;
        if (mimeType != null) {
            mimeString = mimeType.getMimeType();
        }
        c.addEqualsFilter(TemplateCollection.TEMPLATE + "." + Template.MIME_TYPE + "." + MimeType.MIME_TYPE, mimeString);
        if(!c.next()) return null;
        SectionTemplateMapping m = (SectionTemplateMapping)c.getDomainObject();
        // FIXME: There HAS to be a better way to enforce uniqueness here...
        Assert.assertTrue(!c.next());
        c.close();
        return m.getTemplate();
    }

    /**
     * Get the default template for the given use context
     * @deprecated use getDefaultTemplates with the MimeType or use the
     * collection since there can be one default per mime type per context
     */
    protected static Template getDefaultTemplate(ContentSection section, 
                                                 ContentType type, 
                                                 String useContext) {
        SectionTemplateCollection c = getTemplates(section, type, useContext);
        c.addEqualsFilter(IS_DEFAULT, new Boolean(true));
        if(!c.next()) return null;
        SectionTemplateMapping m = (SectionTemplateMapping)c.getDomainObject();
        // FIXME: There HAS to be a better way to enforce uniqueness here...
        Assert.assertTrue(!c.next());
        c.close();
        return m.getTemplate();
    }

    /**
     * Get the default template for the given use context
     */
    protected static SectionTemplateCollection getDefaultTemplates 
        (ContentSection section, ContentType type, String useContext) {
        SectionTemplateCollection c = getTemplates(section, type, useContext);
        c.addEqualsFilter(IS_DEFAULT, new Boolean(true));
        return c;
    }

    /**
     * Retrieve all templates for the given content, type, and use
     * context
     */
    protected static SectionTemplateCollection getTemplates
        (ContentSection section, ContentType type, String useContext) {
        SectionTemplateCollection c = getTemplates(section, type);
        c.addEqualsFilter(USE_CONTEXT, useContext);
        return c;
    }

    /**
     * Retrieve all templates for the given content section and type,
     * along with their use context
     */
    protected static SectionTemplateCollection getTemplates
        (ContentSection section, ContentType type) {
        SectionTemplateCollection c = getTemplates(section);
        c.addEqualsFilter(CONTENT_TYPE + "." + ACSObject.ID, type.getID());
        return c;
    }

    /**
     * Retrieve all templates for the given content section, and all
     * types within it, along with their use context
     */
    protected static SectionTemplateCollection getTemplates(ContentSection section) {
        DataCollection da = SessionManager.getSession().retrieve
            (BASE_DATA_OBJECT_TYPE);
        SectionTemplateCollection c = new SectionTemplateCollection(da);
        c.addEqualsFilter(SECTION + "." + ACSObject.ID, section.getID());
        c.addOrder(CONTENT_TYPE + "." + ContentType.LABEL);
        c.addOrder(USE_CONTEXT);
        c.addOrder(TEMPLATE + "." + ContentItem.NAME);
        return c;
    }

}
