/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.afp.modca;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.fop.afp.AFPLineDataInfo;
import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.ptoca.PtocaProducer;

/**
 * Pages contain the data objects that comprise a presentation document. Each
 * page has a set of data objects associated with it. Each page within a
 * document is independent from any other page, and each must establish its own
 * environment parameters.
 * <p>
 * The page is the level in the document component hierarchy that is used for
 * printing or displaying a document's content. The data objects contained in
 * the page envelope in the data stream are presented when the page is
 * presented. Each data object has layout information associated with it that
 * directs the placement and orientation of the data on the page. In addition,
 * each page contains layout information that specifies the measurement units,
 * page width, and page depth.
 * <p>
 * A page is initiated by a begin page structured field and terminated by an end
 * page structured field. Structured fields that define objects and active
 * environment groups or that specify attributes of the page may be encountered
 * in page state.
 */
public abstract class AbstractPageObject extends AbstractNamedAFPObject implements Completable {

    /** The active environment group for the page */
    protected ActiveEnvironmentGroup activeEnvironmentGroup;

    /** The current presentation text object */
    private PresentationTextObject currentPresentationTextObject;

    /** The list of objects within this resource container */
    protected List objects = new ArrayList();
    protected List<InvokeMediumMap> invokeMediumMaps = new ArrayList<>();

    /** The page width */
    private int width;

    /** The page height */
    private int height;

    /** The page rotation */
    protected int rotation;

    /** The page state */
    protected boolean complete;

    /** The width resolution */
    private int widthRes;

    /** The height resolution */
    private int heightRes;

    /** the object factory */
    protected final Factory factory;

    /**
     * Default constructor
     *
     * @param factory the object factory
     */
    public AbstractPageObject(Factory factory) {
        this.factory = factory;
    }

    /**
     * Main constructor
     *
     * @param factory the object factory
     * @param name the name of this page object
     */
    public AbstractPageObject(Factory factory, String name) {
        super(name);
        this.factory = factory;
    }

    /**
     * Construct a new page object for the specified name argument, the page
     * name should be an 8 character identifier.
     *
     * @param factory
     *            the object factory.
     * @param name
     *            the name of the page.
     * @param width
     *            the width of the page.
     * @param height
     *            the height of the page.
     * @param rotation
     *            the rotation of the page.
     * @param widthRes
     *            the width resolution of the page.
     * @param heightRes
     *            the height resolution of the page.
     */
    public AbstractPageObject(Factory factory,
            String name, int width, int height, int rotation,
            int widthRes, int heightRes) {
        super(name);

        this.factory = factory;
        this.width = width;
        this.height = height;
        this.rotation = rotation;
        this.widthRes = widthRes;
        this.heightRes = heightRes;
    }

    /**
     * Helper method to create a map coded font object on the current page, this
     * method delegates the construction of the map coded font object to the
     * active environment group on the page.
     *
     * @param fontReference
     *            the font number used as the resource identifier
     * @param font
     *            the font
     * @param size
     *            the point size of the font
     */
    public void createFont(int fontReference, AFPFont font, int size) {
        getActiveEnvironmentGroup().createFont(fontReference, font, size, 0);
    }

    /**
     * Helper method to create a line on the current page, this method delegates
     * to the presentation text object in order to construct the line.
     *
     * @param lineDataInfo the line data information.
     */
    public void createLine(AFPLineDataInfo lineDataInfo) {
        boolean success = getPresentationTextObject().createLineData(lineDataInfo);
        if (!success) {
            endPresentationObject();
            getPresentationTextObject().createLineData(lineDataInfo);
        }
    }

    /**
     * Helper method to create text on the current page, this method delegates
     * to the presentation text object in order to construct the text.
     *
     * @param producer the producer
     * @throws UnsupportedEncodingException thrown if character encoding is not supported
     */
    public void createText(PtocaProducer producer) throws UnsupportedEncodingException {
        //getPresentationTextObject().createTextData(textDataInfo);
        boolean success = getPresentationTextObject().createControlSequences(producer);
        if (!success) {
            endPresentationObject();
            getPresentationTextObject().createControlSequences(producer);
        }

    }

    public void createInvokeMediumMap(String name) {
        InvokeMediumMap invokeMediumMap = factory.createInvokeMediumMap(name);
        invokeMediumMaps.add(invokeMediumMap);
    }

    /**
     * Helper method to mark the end of the page. This should end the control
     * sequence on the current presentation text object.
     */
    public void endPage() {
        if (currentPresentationTextObject != null) {
            currentPresentationTextObject.endControlSequence();
        }
        setComplete(true);
    }

    /**
     * Ends the presentation text object
     */
    public void endPresentationObject() {
        if (currentPresentationTextObject != null) {
            currentPresentationTextObject.endControlSequence();
            currentPresentationTextObject = null;
        }
    }

    /**
     * Helper method to create a presentation text object
     * on the current page and to return the object.
     *
     * @return the presentation text object
     */
    public PresentationTextObject getPresentationTextObject() {
        if (currentPresentationTextObject == null) {
            PresentationTextObject presentationTextObject
                = factory.createPresentationTextObject();
            addObject(presentationTextObject);
            this.currentPresentationTextObject = presentationTextObject;
        }
        return currentPresentationTextObject;
    }

    /**
     * Returns the list of {@link TagLogicalElement}s.
     * @return the TLEs
     */
    protected List getTagLogicalElements() {
        if (objects == null) {
            this.objects = new java.util.ArrayList<AbstractStructuredObject>();
        }
        return this.objects;
    }

    /**
     * Creates a TagLogicalElement on the page.
     *
     * @param state the state of the TLE
     */
    public void createTagLogicalElement(TagLogicalElement.State state) {
        TagLogicalElement tle = new TagLogicalElement(state);
        List list = getTagLogicalElements();
        list.add(tle);
    }


    /**
     * Creates a NoOperation on the page.
     *
     * @param content the byte data
     */
    public void createNoOperation(String content) {
        addObject(new NoOperation(content));
    }

    /**
     * Creates an IncludePageSegment on the current page.
     *
     * @param name
     *            the name of the page segment
     * @param x
     *            the x coordinate of the page segment.
     * @param y
     *            the y coordinate of the page segment.
     * @param hard true if hard page segment possible
     */
    public void createIncludePageSegment(String name, int x, int y, boolean hard) {
        IncludePageSegment ips = factory.createIncludePageSegment(name, x, y);
        addObject(ips);
        if (hard) {
            //For performance reasons, page segments can be turned into hard page segments
            //using the Map Page Segment (MPS) structured field.
            getActiveEnvironmentGroup().addMapPageSegment(name);
        }
    }

    /**
     * Returns the ActiveEnvironmentGroup associated with this page.
     *
     * @return the ActiveEnvironmentGroup object
     */
    public ActiveEnvironmentGroup getActiveEnvironmentGroup() {
        if (activeEnvironmentGroup == null) {
            // every page object must have an ActiveEnvironmentGroup
            this.activeEnvironmentGroup
                = factory.createActiveEnvironmentGroup(width, height, widthRes, heightRes);

            if (rotation != 0) {
                switch (rotation) {
                    case 90:
                        activeEnvironmentGroup.setObjectAreaPosition(width, 0, rotation);
                        break;
                    case 180:
                        activeEnvironmentGroup.setObjectAreaPosition(width, height, rotation);
                        break;
                    case 270:
                        activeEnvironmentGroup.setObjectAreaPosition(0, height, rotation);
                        break;
                    default:
                }
            }
        }
        return activeEnvironmentGroup;
    }

    /**
     * Returns the height of the page
     *
     * @return the height of the page
     */
    public int getHeight() {
        return height;
    }

    /**
     * Returns the width of the page
     *
     * @return the width of the page
     */
    public int getWidth() {
        return width;
    }

    /**
     * Returns the rotation of the page
     *
     * @return the rotation of the page
     */
    public int getRotation() {
        return rotation;
    }

    /** {@inheritDoc} */
    protected void writeContent(OutputStream os) throws IOException {
        super.writeContent(os);
        writeObjects(this.objects, os);
    }

    /**
     * Adds an AFP object reference to this page
     *
     * @param obj an AFP object
     */
    public void addObject(Object obj) {
        objects.add(obj);
    }

    /** {@inheritDoc} */
    public void setComplete(boolean complete) {
        this.complete = complete;
    }

    /** {@inheritDoc} */
    public boolean isComplete() {
        return this.complete;
    }
}
