/*
 * blancoDb Enterprise Edition
 * Copyright (C) 2004-2005 Tosiki Iga
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.db.helper;

import java.util.Hashtable;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import blanco.commons.parser.ContentHandlerStream;

/**
 * コンテンツハンドラ・ストリームの単体試験に利用.
 * 
 * @author iga
 */
public class BlancoDbExcelContentHandler extends ContentHandlerStream {

    public BlancoDbExcelContentHandler() {
    }

    public BlancoDbExcelContentHandler(ContentHandlerStream arg) {
        chainContentHandler(arg);
    }

    public void setDocumentLocator(Locator arg0) {
        getContentHandler().setDocumentLocator(arg0);
    }

    public void startDocument() throws SAXException {
        getContentHandler().startDocument();
    }

    public void endDocument() throws SAXException {
        getContentHandler().endDocument();
    }

    public void startPrefixMapping(String arg0, String arg1)
            throws SAXException {
        getContentHandler().startPrefixMapping(arg0, arg1);
    }

    public void endPrefixMapping(String arg0) throws SAXException {
        getContentHandler().endPrefixMapping(arg0);
    }

    public void processingInstruction(String arg0, String arg1)
            throws SAXException {
        getContentHandler().processingInstruction(arg0, arg1);
    }

    public void skippedEntity(String arg0) throws SAXException {
        getContentHandler().skippedEntity(arg0);
    }

    // ここから拡張したいポイント
    private boolean isSheetValid = false;

    private boolean isInParameters = false;

    private String currentElement = "";

    private String currentValue = "";

    private Hashtable queryInfo = null;

    private Hashtable parameterInfo = null;

    public void startElement(String arg0, String arg1, String arg2,
            Attributes arg3) throws SAXException {
        currentElement = arg1;

        if (arg1.equals("blanco-db")) {
            getContentHandler().startElement(arg0, arg1, arg2, arg3);
        } else if (arg1.equals("sheet")) {
            queryInfo = new Hashtable();
        } else if (arg1.equals("attribute")) {
        } else if (arg1.equals("query-type")) {
        } else if (arg1.equals("gamen-id")) {
        } else if (arg1.equals("single")) {
        } else if (arg1.equals("scroll")) {
        } else if (arg1.equals("updatable")) {
        } else if (arg1.equals("name")) {
        } else if (arg1.equals("type")) {
        } else if (arg1.equals("query-line")) {
        } else if (arg1.equals("parameters")) {
            isInParameters = true;
            if (isSheetValid)
                getContentHandler().startElement(arg0, arg1, arg2, arg3);
        } else if (arg1.equals("parameter")) {
            parameterInfo = new Hashtable();
        } else {
            if (isSheetValid)
                getContentHandler().startElement(arg0, arg1, arg2, arg3);
        }
    }

    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {
        if (arg1.equals("blanco-db")) {
            getContentHandler().endElement(arg0, arg1, arg2);
        } else if (isInParameters == false) {
            if (arg1.equals("attribute")) {
                String name = (String) queryInfo.get("name");
                if (name == null) {
                    // 見あたりませんでした。
                    name = "";
                }
                String queryType = (String) queryInfo.get("query-type");
                if (queryType == null) {
                    // 見あたりませんでした。
                    queryType = "";
                }
                boolean isSingle = "true".equals(queryInfo.get("single"));
                String scroll = (String) queryInfo.get("scroll");
                if (scroll == null) {
                    // デフォルトはforward_onlyです。
                    scroll = "forward_only";
                }
                boolean isUpdatable = "true".equals(queryInfo.get("updatable"));

                AttributesImpl attr = new AttributesImpl();
                attr.addAttribute("", "name", "name", "CDATA", name);

                attr.addAttribute("", "single", "single", "CDATA", Boolean
                        .toString(isSingle));
                if ("iterator".equals(queryType)) {
                    if (scroll.equals("false")) {
                        scroll = "forward_only";
                    } else if (scroll.equals("true")) {
                        scroll = "insensitive";
                    }
                    attr.addAttribute("", "scroll", "scroll", "CDATA", scroll);
                    attr.addAttribute("", "updatable", "updatable", "CDATA",
                            Boolean.toString(isUpdatable));
                }

                if ((queryType.equals("iterator") || queryType
                        .equals("invoker"))
                        && name.length() > 0) {
                    isSheetValid = true;
                    if (queryType.equals("iterator")) {
                        getContentHandler().startElement("", "query-iterator",
                                "query-iterator", attr);
                    } else if (queryType.equals("invoker")) {
                        getContentHandler().startElement("", "query-invoker",
                                "query-invoker", attr);
                    }
                }
            } else if (arg1.equals("sheet")) {
                String queryType = (String) queryInfo.get("query-type");
                if (isSheetValid) {
                    if (queryType.equals("iterator")) {
                        getContentHandler().endElement("", "query-iterator",
                                "query-iterator");
                    } else if (queryType.equals("invoker")) {
                        getContentHandler().endElement("", "query-invoker",
                                "query-invoker");
                    }
                }

                // リセット
                isSheetValid = false;
                currentValue = "";
            } else if (arg1.equals("name") || arg1.equals("gamen-id")
                    || arg1.equals("query-type") || arg1.equals("single")
                    || arg1.equals("scroll") || arg1.equals("updatable")) {
                queryInfo.put(arg1, currentValue);
                currentValue = "";
            } else if (arg1.equals("query-line")) {
                String query = "";
                if (queryInfo.get("query") != null) {
                    query = (String) queryInfo.get("query");
                }
                if (query.length() > 0) {
                    query += "\n";
                }
                query += currentValue;
                queryInfo.put("query", query);
                currentValue = "";
            } else if (arg1.equals("query")) {
                String query = "";
                if (queryInfo.get("query") != null) {
                    query = (String) queryInfo.get("query");
                }

                char[] charArray = query.toCharArray();
                if (isSheetValid)
                    getContentHandler().characters(charArray, 0,
                            charArray.length);
                currentValue = "";
                if (isSheetValid)
                    getContentHandler().endElement(arg0, arg1, arg2);
            } else {
                System.out.println("エレメント" + currentElement + "来てます.");
                if (isSheetValid)
                    getContentHandler().endElement(arg0, arg1, arg2);
            }
        } else {
            if (arg1.equals("parameter")) {
                String parameterName = (String) parameterInfo.get("name");
                String parameterType = (String) parameterInfo.get("type");
                if (parameterName == null || parameterType == null) {
                    return;
                }
                AttributesImpl attr = new AttributesImpl();
                attr.addAttribute("", "", "name", "name", parameterName);
                attr.addAttribute("", "", "type", "type", parameterType);
                if (isSheetValid)
                    getContentHandler().startElement("", "parameter",
                            "parameter", attr);
                if (isSheetValid)
                    getContentHandler()
                            .endElement("", "parameter", "parameter");
                currentValue = "";
            } else if (arg1.equals("name") || arg1.equals("type")) {
                parameterInfo.put(arg1, currentValue);
                currentValue = "";
            } else if (arg1.equals("parameters")) {
                // クローズします
                isInParameters = false;
                if (isSheetValid)
                    getContentHandler().endElement(arg0, arg1, arg2);
            } else {
                if (isSheetValid)
                    getContentHandler().endElement(arg0, arg1, arg2);
            }
        }
    }

    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        String value = new String(arg0, arg1, arg2);
        currentValue += value;
    }

    public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
            throws SAXException {
    }
}