/*
 * Copyright 1999-2004 The Apache Software Foundation.
 * 
 * Licensed 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.
 */

package org.apache.cocoon.transformation.pagination;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.cocoon.Modifiable;
import org.apache.cocoon.util.ResizableContainer;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Interprets the pagesheet rules to perform pagination.
 *
 * <pre>
 * FIXME (SM): this code sucks! It was done to show the concept of
 *             rule driven pagination (which I find very nice) but
 *             it needs major refactoring in order to be sufficiently
 *             stable to allow any input to enter without breaking
 *             SAX well-formness. I currently don't have the time to make
 *             it any better (along with implementing the char-based rule
 *             that is mostly useful for text documents) but if you want
 *             to blast the code and rewrite it better, you'll make me happy :)
 * </pre>
 *
 * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
 * @author <a href="mailto:bhtek@yahoo.com">Boon Hian Tek</a>
 * @version CVS $Id: Pagesheet.java,v 1.3 2004/03/05 13:03:00 bdelacretaz Exp $
 */

/*

This is an example pagesheet to show the power of this:

  <?xml version="1.0"?>
  <pagesheet xmlns="http://apache.org/cocoon/paginate/1.0">
   <items>
    <group name="pictures" element="file" namespace="http://apache.org/cocoon/directory/2.0"/>
   </items>
   <rules page="1">
    <count type="element" name="file" namespace="http://apache.org/cocoon/directory/2.0" num="16"/>
     <link type="unit" num="2"/>
     <link type="range" value="10"/>
   </rules>
   <rules>
    <count type="element" name="file" namespace="http://apache.org/cocoon/directory/2.0" num="16"/>
     <link type="unit" num="5"/>
     <link type="range" value="20"/>
   </rules>
   <rules>
     <count type="element" name="file" namespace="http://apache.org/cocoon/directory/2.0" num="16"/>
     <link type="unit" num="5"/>
     <link type="range" value="2"/>
     <link type="range" value="5"/>
     <link type="range" value="10"/>
     <link type="range" value="20"/>
     <link type="range" value="100"/>
   </rules>
  </pagesheet>

which indicates that:

 1) there is one item group called "picture" and each item is given by the
    element "file" of the namespace "http://apache.org/cocoon/directory/2.0".

 2) for the first page, the pagination rules indicate that there are two unit
    links (two above and two below, so linking to page -2 -1 0 +1 +2) and
    range links have value 10 (so they link to page -10 and +10).

 3) for the rest of the pages, there are three unit links (-3 -2 -1 0 +1 +2 +3)
    and range goes 20 (so +20 and -20).

 4) if more than one ranges are defined, range links will be created in sequence

 5) range links will be from big to small (eg. 20, 10, then 5) for backward links,
    range links will be from small to big (eg. 5, 10, then 20) for forward links

 6) range link(s) will have an attribute 'range' to indicate the range size

*/
public class Pagesheet extends DefaultHandler
  implements Cloneable, Modifiable {

    // Used only during parsing of pagesheet document
    private int level = 0;
    private int pg = 0;
    private long lastModified;
    private PageRules rules;

    // Loaded pagesheet information
    ResizableContainer pageRules;

    Map itemGroupsPerName;
    Map itemGroupsPerElement;
    Map itemListsPerName;
    Map itemListsPerElement;

    // Runtime information
    private ResizableContainer pages;
    private Page currentPage = null;
    private int pageCounter = 1;
    private int elementCounter = 0;
    private int descendant = 0;

    private static class Page {

        public int elementStart;
        public int elementEnd;
        public int characters;

        public Page(PageRules rules, int elementStart) {
            this.elementStart = elementStart;

            if (rules.elementCount>0) {
                this.elementEnd = this.elementStart+rules.elementCount-1;
            } else {
                this.elementEnd = this.elementStart+1;
            }
        }

        public boolean validInPage(int elementCounter) {
            return (this.elementStart<=elementCounter) &&
                   (elementCounter<=this.elementEnd);
        }
    }

    private static class ItemList extends ArrayList {

        public ItemList(int capacity) {
            super(capacity);
        }

        public void addItem(int page) {
            this.add(new Integer(page));
        }

        public int getPageForItem(int item) {
            Integer i = (Integer) this.get(item-1);

            return (i==null) ? 0 : i.intValue();
        }

        public boolean valid(int item) {
            return (item==this.size());
        }
    }

    public Pagesheet() {
        this.pages = new ResizableContainer(2);
    }

    private Pagesheet(ResizableContainer rules, Map itemGroupsPerName,
                      Map itemGroupsPerElement) {
        this.pageRules = rules;
        this.itemGroupsPerName = itemGroupsPerName;
        this.itemGroupsPerElement = itemGroupsPerElement;

        this.pages = new ResizableContainer(5);

        if ((this.itemGroupsPerName!=null) &&
            (this.itemGroupsPerElement!=null)) {
            this.itemListsPerName = new HashMap(itemGroupsPerName.size());
            this.itemListsPerElement = new HashMap(itemGroupsPerName.size());

            Iterator iter = itemGroupsPerName.values().iterator();

            for (; iter.hasNext(); ) {
                ItemGroup group = (ItemGroup) iter.next();
                ItemList list = new ItemList(10);

                this.itemListsPerName.put(group.getName(), list);
                this.itemListsPerElement.put(group.getElementURI()+
                                             group.getElementName(), list);
            }
        }
    }

    // --------------- interprets the pagesheet document ----------------

    public void startPrefixMapping(String prefix,
                                   String uri) throws SAXException {
        if ( !uri.equals(Paginator.PAGINATE_URI)) {
            throw new SAXException("The pagesheet's namespace is not supported.");
        }
    }

    public void startElement(String uri, String loc, String raw,
                             Attributes a) throws SAXException {
        level++;
        switch (level) {
            case 1 :
                if (loc.equals("pagesheet")) {
                    // This object represents pagesheet
                    return;
                }
                break;

            case 2 :
                if (loc.equals("rules")) {
                    if (this.pageRules==null) {
                        this.pageRules = new ResizableContainer(2);
                    }
                    String key = a.getValue("page");

                    if (key!=null) {
                        try {
                            pg = Integer.parseInt(key);
                        } catch (NumberFormatException e) {
                            throw new SAXException("Syntax error: the attribute 'rules/@page' must contain a number");
                        }
                    } else {
                        pg = 0;
                    }
                    rules = new PageRules();
                    return;
                } else if (loc.equals("items")) {
                    if (this.itemGroupsPerName==null) {
                        this.itemGroupsPerName = new HashMap(2);
                    }
                    if (this.itemGroupsPerElement==null) {
                        this.itemGroupsPerElement = new HashMap(2);
                    }
                    return;
                }
                break;

            case 3 :
                if (loc.equals("count")) {
                    rules.elementName = a.getValue("name");
                    rules.elementURI = a.getValue("namespace");

                    if (a.getValue("type").equals("element")) {
                        try {
                            rules.elementCount = Integer.parseInt(a.getValue("num"));
                        } catch (NumberFormatException e) {
                            throw new SAXException("Syntax error: the attribute 'count/@num' must contain a number");
                        }
                    } else if (a.getValue("type").equals("chars")) {
                        try {
                            rules.charCount = Integer.parseInt(a.getValue("num"));
                        } catch (NumberFormatException e) {
                            throw new SAXException("Syntax error: the attribute 'count/@num' must contain a number.");
                        }
                    } else {
                        throw new SAXException("Syntax error: count type not supported.");
                    }
                    return;
                } else if (loc.equals("link")) {
                    if (a.getValue("type").equals("unit")) {
                        try {
                            rules.unitLinks = Integer.parseInt(a.getValue("num"));
                        } catch (NumberFormatException e) {
                            throw new SAXException("Syntax error: the attribute 'link/@num' must contain a number.");
                        }
                    } else if (a.getValue("type").equals("range")) {
                        try {
                            rules.addRangeLink(a.getValue("value"));
                        } catch (NumberFormatException e) {
                            throw new SAXException("Syntax error: the attribute 'link/@value' must contain a number.");
                        }
                    } else {
                        throw new SAXException("Syntax error: link type not supported.");
                    }
                    return;
                } else if (loc.equals("group")) {
                    String name = a.getValue("name");

                    if (name==null) {
                        throw new SAXException("Syntax error: the attribute 'group/@name' must be present.");
                    }
                    String elementName = a.getValue("element");

                    if (elementName==null) {
                        throw new SAXException("Syntax error: the attribute 'group/@element' must be present.");
                    }
                    String elementURI = a.getValue("namespace");
                    ItemGroup group = new ItemGroup(name, elementURI,
                                                    elementName);

                    this.itemGroupsPerName.put(name, group);
                    this.itemGroupsPerElement.put(elementURI+elementName,
                                                  group);
                    return;
                }
        }
        throw new SAXException("Syntax error: element "+raw+
                               " is not recognized or is misplaced.");
    }

    public void endElement(String uri, String loc,
                           String raw) throws SAXException {
        level--;
        if (loc.equals("rules")) {
            pageRules.set(pg, rules);
        }
    }

    public void endDocument() throws SAXException {
        if (pageRules.size()==0) {
            throw new SAXException("Pagesheet must contain at least a set of pagination rules.");
        }
        if (pageRules.get(0)==null) {
            throw new SAXException("Pagesheet must contain the global pagination rules.");
        }
    }

    // --------------- process the received element events ----------------

    public void processStartElement(String uri, String name) {
        PageRules rules = getPageRules(pageCounter);

        if (rules.match(name, uri)) {
            elementCounter++;
            descendant++;

            if (currentPage==null) {
                currentPage = new Page(rules, 1);
            }

            if (elementCounter>currentPage.elementEnd) {
                /*System.out.println(">>>> "+pageCounter+
                                   ": Starting new page!!! >>> "+
                                   elementCounter);*/
                pageCounter++;
                currentPage = new Page(rules, currentPage.elementEnd+1);
            }

            pages.set(pageCounter, currentPage);
        }

        if (itemGroupsPerElement!=null) {
            String qname = uri+name;
            ItemGroup group = (ItemGroup) this.itemGroupsPerElement.get(qname);

            if ((group!=null) && (group.match(uri))) {
                ItemList list = (ItemList) this.itemListsPerElement.get(qname);

                if (list!=null) {
                    list.addItem(pageCounter);
                }
            }
        }
    }

    public void processEndElement(String uri, String name) {
        PageRules rules = getPageRules(pageCounter);

        if (rules.match(name, uri)) {
            descendant--;

            if ((rules.charCount>0) &&
                (currentPage.characters>rules.charCount)) {
                // We are over character limit. Flip the page.
                // System.out.println(">>>> " + pageCounter + ": Flipping page!!!");
                currentPage.elementEnd = elementCounter;
            } else if (rules.elementCount==0) {
                // No limit on elements is specified, and limit on characters is not reached yet.
                currentPage.elementEnd++;
            }
        }
    }

    public void processCharacters(char[] ch, int index, int len) {
        if (descendant>0) {
            // Count amount of characters in the currect page.
            // System.out.println(">>>> " + pageCounter + ": " + new String(ch, index, len) + " (" + len + " bytes)");
            currentPage.characters += len;
        }
    }

    // --------------- return the pagination information ----------------

    public boolean isInPage(int page, int item, String itemGroup) {
        return ((descendant==0) || valid(page, item, itemGroup));
    }

    public int getTotalPages() {
        return pageCounter;
    }

    public int getTotalItems(String itemGroup) {
        if (this.itemListsPerName==null) {
            return 0;
        }
        ItemList list = (ItemList) this.itemListsPerName.get(itemGroup);

        return (list==null) ? 0 : list.size();
    }

    public int getPageForItem(int item, String itemGroup) {
        if (this.itemListsPerName==null) {
            return 0;
        }
        ItemList list = (ItemList) this.itemListsPerName.get(itemGroup);

        return (list==null) ? 0 : list.getPageForItem(item);
    }

    public int itemCount(String elementURI, String elementName) {
        if (this.itemListsPerElement==null) {
            return 0;
        }
        ItemList list = (ItemList) this.itemListsPerElement.get(elementURI+
                            elementName);

        return (list==null) ? 0 : list.size();
    }

    public String getItemGroupName(String elementURI, String elementName) {
        if (this.itemListsPerElement==null) {
            return null;
        }
        return ((ItemGroup) this.itemGroupsPerElement.get(elementURI+
            elementName)).getName();
    }

    // ---------------- miscellaneous methods ----------------------------

    private boolean valid(int page, int item, String itemGroup) {
        if (item==0) {
            Page p = (Page) pages.get(page);

            return (p!=null) && (p.validInPage(elementCounter));
        } else {
            if (this.itemListsPerElement==null) {
                return false;
            }
            ItemList list = (ItemList) this.itemListsPerName.get(itemGroup);

            return (list!=null) && (list.valid(item));
        }
    }

    public PageRules getPageRules(int page) {
        PageRules p = (PageRules) pageRules.get(page);

        return (p!=null) ? p : (PageRules) pageRules.get(0);
    }

    public void setLastModified(long lastModified) {
        this.lastModified = lastModified;
    }

    public boolean modifiedSince(long date) {
        return (this.lastModified == 0 || date!=this.lastModified);
    }

    public Object clone() {
        return new Pagesheet(pageRules, itemGroupsPerName,
                             itemGroupsPerElement);
    }
}
