/*
 * @(#)GenerateNavibar.java
 *
 * RID-X    : Generator 製作指示書/紙芝居の NaviBar生成
 *
 * @author  Intelligent Technology Inc.
 * @version 1.01 2002/01/23
 *
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 */
package jp.co.nri.rid.generator;

import java.io.*;
import java.util.*;
import org.w3c.dom.*;


import jp.co.nri.rid.mapper.*;
import jp.co.nri.rid.error.*;
import jp.co.nri.rid.snapshot.*;

/**
 * Rid 製作指示書/紙芝居の NaviBar生成
 */
public class GenerateNavibar extends GenerateParser {

    /** ナビバータイプ：製作指示書 **/
    final   static public String PRODUCT = "Product";
    /** ナビバータイプ：紙芝居    **/
    final   static public String PRESENT = "Present";

    /** テンプレートディレクトリ    **/
    private static String gn_templateDir = "";
    /** 出力ディレクトリ    **/
    private static String gn_outDir      = "";
    /** ナビバーのタイプ    **/
    private static String gn_type        = "";

    /** ナビバー  index.html  **/
    private static final String prAdminIndex  = "../Admin/index.html";
    /** ナビバー  index_1.html  **/
    private static final String prAdminIndex1 = "../Admin/index_1.html";
    /** ナビバー  index_2.html  **/
    private static final String prAdminIndex2 = "../Admin/index_2.html";
    /** ナビバー  index_3.html  **/
    private static final String prAdminIndex3 = "../Admin/index_3.html";
    /** ナビバー  index_4.html  **/
    private static final String prAdminIndex4 = "../Admin/index_4.html";
    /** ナビバー  index_5.html  **/
    private static final String prAdminIndex5 = "../Admin/index_5.html";

    /** ナビバーデータ  **/
    class NaviData {
        String        linkStart;
        String        name;
        String        linkEnd;
    }


/**
  * デフォルトコンストラクタ
  */
    public GenerateNavibar() {}


/**
  * ナビバーの作成
  *
  * @param  String      type            製作指示書／紙芝居のタイプ
  * @param  String      template_dir    テンプレートディレクトリ
  * @param  String      out_dir         出力ディレクトリ
  * @param  ZoneInfo    zone            Zoneの情報
  * @param  ZoneInfo    parent          親Zoneの情報
  */
    public boolean generate(String type, String template_dir, String out_dir, ZoneInfo zone, ZoneInfo parent) throws Exception {

        boolean ret = false;

        //テンプレートディレクトリ
        gn_templateDir = template_dir;
  
        //出力先
        gn_outDir = out_dir;

        //ナビバーの種類
        gn_type = type;

        //ナビバーの作成
        generateNavi(zone, parent);

        return true;
    }


/**
  *  NaviDataの生成
  *
  * @param  String      link            linkするHTMLファイル
  * @param  String      alt             <A>TagのALT
  * @return MapData
  */
    private NaviData createNaviData(String href, String alt) throws Exception {

        NaviData mapData  = new NaviData();
        mapData.linkStart = replaceWebFileSeparator("<a href=\"" + href + "\" target=\"_top\">");
        mapData.name      = alt;
        mapData.linkEnd   = "</a>";
        return mapData;
    }


/**
  * 製作指示書用のNaviDataを作成
  *
  * @param  ZoneInfo    zone            Zone情報
  * @return NaviData
  */
    private NaviData naviProductData(ZoneInfo zone) throws Exception {

        String link;
        if (gn_type.compareTo(PRODUCT) == 0) {
            //製作指示書のナビバーの場合
            link = zone.parent + puOutRefresh;
        } else {
            //紙芝居のナビバーの場合
            link = zone.parent + "../" + puProductDir + "/" + puOutRefresh;
        }
       return (createNaviData(link,""));
    }


/**
  * 紙芝居用のNaviDataを作成
  *
  * @param  ZoneInfo    zone            Zone情報
  * @return NaviData
  */
    private NaviData naviPresentData(ZoneInfo zone) throws Exception {

        String link;

        if (gn_type.compareTo(PRESENT) == 0) {
            //紙芝居のナビバーの場合
            link = zone.parent + puOutRefresh;
        } else {
            //製作指示書のナビバーの場合
            link = zone.parent + "../" + puPresentDir + "/" + puOutRefresh;
        }
        return (createNaviData(link,""));
    }


/**
  * ナビ情報の生成
  *   Zoneに含まれるPageUnitのを読み
　*   NaviBar用にPage情報リストを作成する
  * 
  * @param  ZoneInfo    zone            Zone情報
  * @return Vector      Page情報のリスト
  */
    private Vector naviPageLst(ZoneInfo zone) throws Exception {

        Vector  lst = new Vector();

        for ( int i = 0; i < zone.page_lst.size(); i++ ) {
            PageInfo page_info = (PageInfo)zone.page_lst.elementAt(i);

            NaviData pageData = naviPage(page_info);
            if (pageData != null) lst.add(pageData);
        }

        return lst;
    }


/**
  * ナビバーの情報（zone）
  *
  * @param  PageInfo    page_info       Pageの情報
  * @return MapDataのリスト
  * 製作指示書の生成
  */
    private NaviData naviPage(PageInfo page) throws Exception {
        return(createNaviData(page.name + puOutFrame, page.name));
    }


/**
  * ナビ情報の生成
  *   Zoneに含まれるZoneUnitのを読み
　*   NaviBar用にZone情報リストを作成する
  * 
  * @param  ZoneInfo    zone            Zone情報
  * @return Vector      Page情報のリスト
  */
    private Vector naviZoneLst(ZoneInfo zone) throws Exception {

        Vector  lst = new Vector();

        for ( int n = 0; n < zone.zone_lst.size(); n++ ) {
            ZoneInfo zone_info = (ZoneInfo)zone.zone_lst.elementAt(n);

            //ナビバーの情報（Zone）
            NaviData zoneData = naviZone(zone_info);
            if (zoneData != null) lst.add(zoneData);
        }

        return lst;
  }


/**
  * ナビバーの情報（zone）
  *
  * @param  ZoneInfo    zone_info       Zoneの情報
  * @return MapDataのリスト
  */
    private NaviData naviZone(ZoneInfo zone) throws Exception {

        String href;

        //ZONE内にPageが存在するか？
        if (zone.page_lst.size() > 0){
            // Pageが存在する場合、先頭のページを表示する
            PageInfo page_info = (PageInfo)zone.page_lst.elementAt(0);
            href = zone.name +"/" + page_info.name + puOutFrame;
            
        } else {
            // Pageが存在しない場合、空白のページを表示する
            href=  zone.name +"/" + puBlank + puOutFrame;
        }
        return(createNaviData(href, zone.name));
    }


/**
  * ナビ情報の生成
  *   親Zoneに含まれるZoneUnitのを読み
　*   NaviBar用にZone情報リストを作成する
  * 
  * @param  ZoneInfo    zone            親Zone情報
  * @return Vector      親Page情報のリスト
  */
    private Vector naviParentLst(ZoneInfo parent) throws Exception {

        Vector  lst = new Vector();

        if (parent != null) {
            //ナビバーの情報（parent）
            NaviData parentData = naviParent(parent);
            if (parentData != null) lst.add(parentData);
        }
        return lst;
  }


/**
  * ナビバーの情報（parent）
  *
  * @param  ZoneInfo    zone_info       Zoneの情報
  * @return MapDataのリスト
  */
    private NaviData naviParent(ZoneInfo zone) throws Exception {

        String href;
        String alt;

        //ZONE内にPageが存在するか？
        if (zone.page_lst.size() > 0){
            // Pageが存在する場合、先頭のページを表示する
            PageInfo page_info = (PageInfo)zone.page_lst.elementAt(0);
            href = "../" + page_info.name + puOutFrame;
            alt  = zone.name + "/" + page_info.name + puOutFrame;
        } else {
            // Pageが存在しない場合、Blankページを表示する
            href = "../" + puBlank + puOutFrame;
            alt  = zone.name + "/" + puBlank + puOutFrame;
        }
        return(createNaviData(href, alt));
    }


/**
  * ナビの生成
  *
  * @param  ZoneInfo    zone            Zoneの情報
  * @param  ZoneInfo    parent          親Zoneの情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean generateNavi(ZoneInfo zone, ZoneInfo parent) throws Exception {
 
        boolean ret = false;
        String out = "";
        xcopy xc = new xcopy();
        RidMessage ridMsg = new RidMessage();

        // _navi,html有無判断
        String template = gn_templateDir + File.separator + puTemplNavi;
        if ( !xc.fileExists(template) ){
            throw new RidException(ridMsg.Error("E4001", template));
        }

        //出力ファイル名 TOP ZoneUnitの場合は true
        if (zone.top) {
            out = gn_outDir + File.separator + zone.name + puOutNavi;
        } else {
            out = gn_outDir + File.separator + zone.file + File.separator + zone.name + puOutNavi;
        }

        //Map Dataの生成
        Document temp_data = generateNaviData(zone, parent);

        //XmlUtil xu = new XmlUtil();
        //xu.writeDocment2XMLFile(new File(".", "mapperType3.xml"), temp_data);

        //ナビバーのHTML生成
        Mapper mapper = new Mapper();
        ret = mapper.Type3(template, temp_data, out);
        if (!ret) {
            throw new RidException(ridMsg.Error("E4002", mapper.getErrorString()));
        }
        return ret;
    }


/**
  * ナビデータの生成
  *
  * @param  ZoneInfo    zone            Zoneの情報
  * @param  ZoneInfo    parent          親Zoneの情報
  * @return Document    ドュメント
  */
    private Document generateNaviData(ZoneInfo zone, ZoneInfo parent) throws Exception {

        Document doc = new org.apache.xerces.dom.DocumentImpl();
        Element topElem = doc.createElement(puRootTag);
        doc.appendChild(topElem);

        // home
        NaviData homeData = createNaviData(zone.parent + prAdminIndex, "");
        writeNaviData(topElem, "HomeData", homeData);

        // index1
        NaviData index1Data = createNaviData(zone.parent + prAdminIndex1, "");
        writeNaviData(topElem, "Index1", index1Data);

        // index2
        NaviData index2Data = createNaviData(zone.parent + prAdminIndex2, "");
        writeNaviData(topElem, "Index2", index2Data);

        // index3
        NaviData index3Data = createNaviData(zone.parent + prAdminIndex3, "");
        writeNaviData(topElem, "Index3", index3Data);

        // index4
        NaviData index4Data = createNaviData(zone.parent + prAdminIndex4, "");
        writeNaviData(topElem, "Index4", index4Data);

        // index5
        NaviData index5Data = createNaviData(zone.parent + prAdminIndex5, "");
        writeNaviData(topElem, "Index5", index5Data);

        // 製作指示書
        NaviData productData = naviProductData(zone);
        writeNaviData(topElem, "ProductData", productData);

        // 紙芝居
        NaviData presentData = naviPresentData(zone);
        writeNaviData(topElem, "PresentData", presentData);

        // 親Zone
        Vector parent_lst = naviParentLst(parent);
        for ( int i = 0; i < parent_lst.size(); i++ ) {
            NaviData parentData = (NaviData)parent_lst.elementAt(i);
            writeNaviData(topElem, "ParentData", parentData);
        }

        // ページ
        Vector page_lst = naviPageLst(zone);
        for ( int i = 0; i < page_lst.size(); i++ ) {
            NaviData pageData = (NaviData)page_lst.elementAt(i);
            writeNaviData(topElem, "PageData", pageData);
        }

        // 子Zone
        Vector zone_lst = naviZoneLst(zone);
        for ( int i = 0; i < zone_lst.size(); i++ ) {
            NaviData zoneData = (NaviData)zone_lst.elementAt(i);
            writeNaviData(topElem, "ZoneData", zoneData);
        }
        return doc;
    }


/**
  * ナビデータの出力
  *
  * @param  Element     topElem         Element
  * @param  String      repeaNamet      リピート名
  * @param  NaviData    naviData        ナビデータ
  * @return void
  */
    private void writeNaviData(Element topElem, String repeatName, NaviData naviData) throws Exception {

        XmlUtil xu = new XmlUtil();
        Element elem = xu.createSubElement(topElem, repeatName);
        xu.createOrSetTextValue(elem, "linkStart", naviData.linkStart);
        xu.createOrSetTextValue(elem, "imageAlt",  naviData.name);
        xu.createOrSetTextValue(elem, "linkEnd",   naviData.linkEnd);
    }
}
