/*
 * @(#)GeneratePresent.java
 *
 * RID-X    : Generator 紙芝居生成
 *
 * @author    Intelligent Technology Inc.
 * @version   1.01 2001/12/21
 *
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 */
package jp.co.nri.rid.generator;

import java.io.*;
import java.util.*;
import java.text.*;
import java.net.URL;
import java.util.Random;
import org.w3c.dom.*;

import jp.co.iti.fagot.ZApp;
import jp.co.iti.fagot.doc.DocDocument;
import jp.co.iti.fagot.doc.DocManager;
import jp.co.iti.fagot.util.ZDebug;
import jp.co.iti.fagot.util.ZResource;
import jp.co.iti.fagot.util.ZProperties;
import jp.co.iti.fagot.util.ZString;


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


/**
 * Rid 紙芝居生成
 */
public class GeneratePresent extends GenerateParser {

    /** rid.template.dirプロパティ  **/
    final static public String RID_TEMPLATE_DIR = "rid.template.dir";
    /** rid.parts.dirプロパティ  **/
    final static public String RID_PARTS_DIR    = "rid.parts.dir";
    /** rid.public.dirプロパティ  **/
    final static public String RID_PUBLIC_DIR   = "rid.public.dir";
    /** rid.html.dirプロパティ  **/
//    final static public String RID_HTML_DIR     = "rid.html.dir";

    /** TOP　URL  **/
    private static String pr_url;
    /** テンプレートディレクトリ  **/
    private static String pr_templateDir;
    /** テンプレートディレクトリ  **/
    private static String pr_partsDir;
    /** 出力ディレクトリ  **/
    private static String pr_outDir;
    /** TOP　URL  **/
    private static String pr_htmlDir;

/**
  * デフォルトコンストラクタ
  */
    public GeneratePresent() {
        pr_url = "";                        // TOP URL
        pr_templateDir = "";                // テンプレートディレクトリ
        pr_partsDir    = "";                // テンプレートディレクトリ
        pr_outDir      = "";                // 出力ディレクトリ
        pr_htmlDir     = "";                // htmlディレクトリ
    }


/**
  * 紙芝居生成
  *
  * @param  Document    doc             ドキュメント
  * @param  String      project_dir     プロジェクトディレクトリ
  * @return boolean     true（成功）/ false（失敗）
  */
    public boolean generate(Document doc, String project_dir) throws Exception {

        boolean ret = false;
        RidMessage ridMsg = new RidMessage();

        getDir(project_dir);

        //紙芝居のディレクトリの内容を削除する
        erase del = new erase();
        ret = del.directory(pr_outDir);
        if(!ret)  ZDebug.trace(ridMsg.Warning("W4003", pr_outDir));

        // documentの解析
        ProjectInfo  project_info = new ProjectInfo();
        project_info = documentParser(doc, "", parentPath(pr_outDir, pr_htmlDir));

        // 紙芝居の生成
        ret = generatePresent(project_info);

        return true;
    }


/**
  * TOP URLの取得
  *
  * @return String      TOP　URL
  */
    public String getUrl() throws Exception {
        return pr_url;
    }


/**
  * TOP URLの設定
  *
  * @param  String      url             TOP URL
  * @return void
  */
    private void setUrl(String url) throws Exception {
        pr_url = url;
    }


/**
  * 紙芝居の生成
  *
  * @param  ProjectInfo project         プロジェクト情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean generatePresent(ProjectInfo project) throws Exception {

        boolean ret = false;
        String refresh = "";

        //Top Zone情報
        ZoneInfo zone_info = project.zone;
        ret = presentZoneInfo(zone_info, null);

        if (ret) {
            if (zone_info.page_lst.size() != 0) {
                //TOP URL
                PageInfo page_info = (PageInfo)zone_info.page_lst.elementAt(0);
                setUrl(page_info.url);
                refresh = page_info.name;
            } else {
                setUrl(pr_outDir + File.separator + puBlank + puOutFrame);
                refresh = puBlank;
            }

            //紙芝居のリフレッシュを作成 
            GenerateRefresh   gr = new GenerateRefresh();
            gr.generateRefresh(pr_templateDir, pr_outDir, refresh);
        }
        return ret;
    }

/**
  * 紙芝居の生成(ZONE)
  *
  * @param  ZoneInfo    zone            Zone情報
  * @param  ZoneInfo    parent          親Zone情報
  * @return void
  */
    private boolean presentZoneInfo(ZoneInfo zone, ZoneInfo parent) throws Exception {

        boolean ret = false;

        //ディレクトリの作成 Zoneのトップ以外
        if ( !zone.top ) {
            xcopy xc = new xcopy();
            xc.makeDir(pr_outDir + File.separator + zone.file); 
        }

        //Page情報
        if (zone.page_lst.size() > 0) {
            //Zoneにページが存在する
            for ( int i = 0; i < zone.page_lst.size(); i++ ) {
                PageInfo page_info = (PageInfo)zone.page_lst.elementAt(i);
                ret = presentPageInfo(zone, page_info);
                if (!ret) return false;
            }
        } else {
            //ページが存在しない場合は、Blankフレームを作成する
            presentFrame(zone, null);
        }

        //Zone情報
        for ( int n = 0; n < zone.zone_lst.size(); n++ ) {
            ZoneInfo zone_info = (ZoneInfo)zone.zone_lst.elementAt(n);
            ret = presentZoneInfo(zone_info, zone);
            if (!ret) return false;
        }

        // ナビ
        GenerateNavibar gn = new GenerateNavibar();
        ret = gn.generate(GenerateNavibar.PRESENT, pr_templateDir, pr_outDir, zone, parent);

        return ret;
    }



/**
  * 紙芝居の生成(PAGE)
  *
  * @param  String      zone_name       Zone名（ディレクトリ）
  * @param  PageInfo    page            ページ情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean presentPageInfo(ZoneInfo zone, PageInfo page) throws Exception {

        boolean ret = false;

        // フレームの作成
        ret = presentFrame(zone,  page);
        //ここではページ生成しない　2002/08/13
        //if (ret) {
        //    // ページの生成
        //    GeneratePage gp = new GeneratePage();
        //    ret = gp.generate(pr_htmlDir, pr_templateDir, pr_partsDir, zone, page);
        //}
        return ret;
    }

/**
  * フレームの生成
  *
  * @param  String      zone_name       Zone名
  * @param  PageInfo    page            ページ情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean presentFrame(ZoneInfo zone, PageInfo page) throws Exception {

        boolean ret = false;
        xcopy xc = new xcopy();
        RidMessage ridMsg = new RidMessage();

        // _framePresent.html有無判定
        String template = pr_templateDir + File.separator + puTemplPreFrame;
        if ( !xc.fileExists(template) ){
            throw new RidException(ridMsg.Error("E4001", template));
        }

        // _frame_map.xml有無判定
        String map = pr_templateDir + File.separator + puMapFrame;
        if ( !xc.fileExists(map) ) {
            throw new RidException(ridMsg.Error("E4001", map));
        }

        // 出力ファイル名
        String out;
        if (page != null) {
            out = pr_outDir + File.separator + page.file + puOutFrame;
            page.url = out;
        } else {
            if (zone.top){
                out = pr_outDir + File.separator + puBlank + puOutFrame;
            } else {
                out = pr_outDir + File.separator + zone.file + File.separator + puBlank + puOutFrame;
            }
        }

        //Map Dataの生成
        Document map_data = presentFrameMapData(zone.name, page);

        //フレームのHTML生成　(Mapper=Template + Map + MapData)
        Mapper mapper = new Mapper();
        if( !mapper.Type1(template, map, map_data, out)) {
            throw new RidException(ridMsg.Error("E4002",mapper.getErrorString()));
        }

        return true;
    }



/**
  * フレームのデータ生成
  *
  * @param  String      navi_name       NAVI HTMLファイル名
  * @param  String      html_name       HTMLファイル名
  * @return Document    フレームのドュメント
  */
    private Document presentFrameMapData(String zone_name, PageInfo page) throws Exception {

        XmlUtil xu = new XmlUtil();
        Element page_elem;
//        Attr attr;

        // ドュメント生成
        Document doc = new org.apache.xerces.dom.DocumentImpl();
        Element topElem = doc.createElement(puRootTag);
        doc.appendChild(topElem);

        // ナビ
        String navi = zone_name + puTemplNavi;
        page_elem = xu.createSubElement(topElem, puMapFrameData);
		page_elem.setAttribute(puMapFrameDataKey, "navi");
//        attr = xu.createOrGetAttribute(page_elem, puMapFrameDataKey);
//        xu.createOrSetTextValue((Node)attr, "navi");
        xu.createOrSetTextValue(page_elem, puMapFrameInTag, navi);

        if (page != null) {
            // メイン
            String html_file  = replaceWebFileSeparator(page.path + File.separator + page.file);
            page_elem = xu.createSubElement(topElem, puMapFrameData);
			page_elem.setAttribute(puMapFrameDataKey, "main");
//            attr = xu.createOrGetAttribute(page_elem, puMapFrameDataKey);
//            xu.createOrSetTextValue((Node)attr, "main");
            xu.createOrSetTextValue(page_elem, puMapFrameInTag, html_file);
        }
        return doc;
    }

/**
  * ディレクトリの取得
  *
  * @param  String      project_dir   プロジェクトディレクトリ
  * @return void
  */
    private void getDir(String project_dir) throws Exception {

        ZResource res = ZApp.getTheApp().getResource();

        String template_dir = res.getString(RID_TEMPLATE_DIR);          // テンプレートディレクトリ
        String parts_dir    = res.getString(RID_PARTS_DIR);             // テンプレートディレクトリ（パーツ）
        String out_dir      = res.getString(RID_PUBLIC_DIR);            // 出力ディレクトリ
//        String html_dir     = res.getString(RID_HTML_DIR);              // htmlディレクトリ

        pr_templateDir = project_dir + File.separator + template_dir;   // テンプレートディレクトリ
        pr_outDir      = project_dir + File.separator + out_dir;        // 出力ディレクトリ
//        pr_htmlDir     = project_dir + File.separator + html_dir;       // htmlディレクトリ
        pr_htmlDir     = Ridual.getHtmlDir();       // htmlディレクトリ
        pr_partsDir    = project_dir + File.separator + parts_dir;      // テンプレートディレクトリ
    }

}
