/*
 * (C) Copyright IBM Corp. 1997-1998  All rights reserved.
 *
 * US Government Users Restricted Rights Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */

package com.ibm.xml.sample;

import com.ibm.xml.parser.*;
import java.io.*;
import java.util.Hashtable;

/**
 * A sample to label "positions" to elements.
 *
 * @version 1.1
 * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
 */
public class Positioning {
    public static void main(String[] argv) {
        if (1 != argv.length) {
            System.err.println("Require 1 filename.");
            System.exit(1);
        }
        try {
            FileInputStream is = new FileInputStream(argv[0]);
            Parser parser = new Parser(argv[0]);
            MyFactory mf = new MyFactory();
            parser.setElementFactory(mf);
            parser.setTagHandler(mf);
            TXDocument doc = parser.readStream(is);

            /* some process */

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Positions in children list.
     */
    static interface Position {
        int getPosition();
        void setPosition(int pos);
        int getPositionByType();
        void setPositionByType(int pos);
    }
    static class EXElement extends TXElement implements Position {
        int m_childposition = -1;
        int m_typeposition = -1;
        int m_nodecount_start = -1;
        int m_nodecount_end = -1;

        public int getPosition() {
            return m_childposition;
        }
        public void setPosition(int pos) {
            m_childposition = pos;
        }
        public int getPositionByType() {
            return m_typeposition;
        }
        public void setPositionByType(int pos) {
            m_typeposition = pos;
        }
        int getStartCount() {
            return m_nodecount_start;
        }
        void setStartCount(int v) {
            m_nodecount_start = v;
        }
        int getEndCount() {
            return m_nodecount_end;
        }
        void setEndCount(int v) {
            m_nodecount_end = v;
        }
        boolean isInside(EXElement elem) {
            return m_nodecount_start < elem.getStartCount()
                && elem.getEndCount() < m_nodecount_end;
        }
        boolean isInside(EXText text) {
            return m_nodecount_start < text.getCount()
                && text.getCount() < m_nodecount_end;
        }
        public EXElement(String name) {
            super(name);
        }
    }
    static class EXText extends TXText implements Position {
        int m_childposition = -1;
        int m_typeposition = -1;
        int m_nodecount = -1;

        public int getPosition() {
            return m_childposition;
        }
        public void setPosition(int pos) {
            m_childposition = pos;
        }
        public int getPositionByType() {
            return m_typeposition;
        }
        public void setPositionByType(int pos) {
            m_typeposition = pos;
        }
        int getCount() {
            return m_nodecount;
        }
        void setCount(int i) {
            m_nodecount = i;
        }
        public EXText(String data) {
            super(data);
        }
    }

    static class MyFactory extends DefaultElementFactory implements TagHandler {
        int m_counter = 0;

        public TXElement createElement(String name) {
            EXElement el = new EXElement(name);
            el.setFactory(this);
            return el;
        }

        public TXText createText(String data) {
            EXText te = new EXText(data);
            te.setFactory(this);
            te.setCount(m_counter++);
            return te;
        }

        public void handleStartTag(TXElement elem, boolean empty) {
            ((EXElement)elem).setStartCount(m_counter++);
        }
        public void handleEndTag(TXElement elem, boolean empty) {
            ((EXElement)elem).setEndCount(m_counter++);

            // Position
            org.w3c.dom.NodeIterator ni = elem.getChildNodes();
            Hashtable hash = new Hashtable();
            int counter = 0;
            org.w3c.dom.Node n;
            while (null != (n = ni.toNextNode())) {
                if (n instanceof Position)
                    ((Position)n).setPosition(counter);
                counter ++;
                String name = null;
                if (n instanceof EXText) {
                    name = "#PCDATA";
                } else if (n instanceof EXElement) {
                    name = ((EXElement)n).getTagName();
                }
                if (null != name) {
                    Integer i = (Integer)hash.get(name);
                    int v = 0;
                    if (null == i) {
                        hash.put(name, new Integer(0));
                    } else {
                        v = i.intValue()+1;
                        hash.put(name, new Integer(v));
                    }
                    ((Position)n).setPositionByType(v);
                }
            }
        }
    }
}
