package org.itscool.stylist.io;

import java.io.IOException;
import java.util.LinkedList;

import org.itscool.commons.document.XmlConfigReader;
import org.itscool.stylist.mapping.LayoutMapping;
import org.itscool.stylist.mapping.LayoutPutMapping;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * &lt;include-mappings&gt;要素を解析するクラスです
 * @author KANO
 * @since jdk1.4.1
 * @version 1.00A 2004/11/1
 */
public class LayoutConfigReader extends XmlConfigReader{
    /**
     * XMLファイルから&lt;include-mappings&gt;要素を解析します<br>
     * 解析結果はnodeListにセットします<br>
     * @param hashMap XMLの解析結果
     */
    protected void doCreate(LinkedList hashMap) throws IOException{
        /* ルートタグ名を取得 */
        Element root = document.getDocumentElement();
        if( root == null ){
            String err = "Can not root element at stylist-config.xml(" +
                getClass().getName()+")";
            throw new IOException(err);
        }
        /* include-mappings の取得*/
        NodeList includeList = root.getElementsByTagName("layout-mappings");
        if( includeList == null ){
            String err = "Can not element at <layout-mappings>(" +
                getClass().getName()+")";
            throw new IOException(err);
        }
        Node include = includeList.item(0);
        if( include != null ){
            createIncludes(include, hashMap);
        }
    }
    
    /**
     * &lt;include&gt;要素を解析します
     * @param includes &lt;include&gt;要素
     * @param hashMap 解析後の&lt;include&gt;情報を追加するノードリスト
     * @throws Exception
     */
    protected void createIncludes(Node includes, LinkedList hashMap){
        NodeList includesChilds = includes.getChildNodes();
        
        for( int i = 0; i < includesChilds.getLength(); i++) {
            Node include = includesChilds.item(i);
            if( include.getNodeName().equals("layout")){
                createInclude(include, hashMap);
            }
        }
    }
    
    /**
     * &lt;include&gt;要素の属性を解析します
     * @param include &lt;include&gt;要素
     * @param hashMap 解析後の&lt;include&gt;情報を追加するノードリスト
     * @throws Exception
     */
    protected void createInclude(Node include, LinkedList hashMap){
        NamedNodeMap attributes = include.getAttributes();
        Node path = attributes.getNamedItem("path");
        Node name = attributes.getNamedItem("name");
        Node extendz = attributes.getNamedItem("extends");
        /*
        System.out.print("[" + include.getNodeName() + "] ");
        System.out.print(name.getNodeName() + ":" + name.getNodeValue() + " , ");
        System.out.println(path.getNodeName() + ":" + path.getNodeValue());
         */
        LayoutMapping includeMapping = new LayoutMapping(name.getNodeValue());
        
        includeMapping.setPath(path.getNodeValue());
        if(extendz != null){
            includeMapping.setExtendz(extendz.getNodeValue());
        }
        NodeList includeChilds = include.getChildNodes();
        for( int i=0; i<includeChilds.getLength(); i++ ){
            Node put = includeChilds.item(i);
            if( put.getNodeName().equals("put")){
                createPut(put, includeMapping );
            }
        }
        hashMap.addFirst(includeMapping );
        
    }
    
    /**
     * インクルード情報を作成します
     * @param put XMLから読み込んだインクルード情報
     * @param includeMapping LayoutMappingインスタンス
     */
    protected void createPut(Node put, LayoutMapping includeMapping){
        NamedNodeMap attributes = put.getAttributes();
        Node path = attributes.getNamedItem("path");
        Node name = attributes.getNamedItem("name");
        
        LayoutPutMapping putMapping = new LayoutPutMapping(name.getNodeValue(), path.getNodeValue());
        /*
        System.out.print("[" + put.getNodeName() + "] ");
        System.out.print(name.getNodeName() + ":" + name.getNodeValue() + " , ");
        System.out.println(path.getNodeName() + ":" + path.getNodeValue());
         */
        includeMapping.addPut(name.getNodeValue(), putMapping );
    }
}
