/*
 * @(#)GenerateProduct.java
 *
 * RID-X    : Generator 製作指示書生成
 *
 * @author  Intelligent Technology Inc.
 * @version 1.01 2002/03/01
 *
 * 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.Ridual;
import jp.co.nri.rid.mapper.*;
import jp.co.nri.rid.snapshot.xcopy;
import jp.co.nri.rid.snapshot.erase;
import jp.co.nri.rid.error.*;

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;
/**
 * Rid 製作指示書生成
 */
public class GenerateProduct 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.team.dirプロパティ  **/
    final static public String RID_TEAM_DIR     = "rid.team.dir";
    /** rid.html.dirプロパティ  **/
//    final static public String RID_HTML_DIR     = "rid.html.dir";
    /** rid.pagesvg.dirプロパティ  **/
    final static public String RID_PAGESVG_DIR  = "rid.pagesvg.dir";

    /** TOP　URL  **/
    protected String pr_url;
    /** テンプレートディレクトリ  **/
    protected String pr_templateDir;
    /** テンプレート(パーツ)ディレクトリ  **/
    protected String pr_partsDir;
    /** 出力ディレクトリ  **/
    protected String pr_outDir;
    /** htmlディレクトリ  **/
    protected String pr_htmlDir;
    /** SVGディレクトリ   **/
    protected String pr_svgDir;


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


/**
  * 製作指示書生成
  *
  * @param  Document    doc             ドキュメント
  * @param  String      project_dir     プロジェクトディレクトリ
  * @return boolean     true(成功)/false(失敗)
  */
    public boolean generate(Document doc, String project_dir) throws RidException, 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 = generateProduct(project_info);

        return ret;
    }


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


/**
  * TOP URLの取得
  *
  * @return String      TOP URL
    public String getTopUrl(Document doc, String project_dir) throws RidException, Exception  {

        String url = "";

        //ディレクトリの取得
        getDir(project_dir);

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

        ZoneInfo zone_info = project_info.zone;
        if (zone_info.page_lst.size() != 0) {
          PageInfo page_info = (PageInfo)zone_info.page_lst.elementAt(0);
          url = pr_outDir + File.separator + page_info.file + puOutFrame;
        } else {
          url = pr_outDir + File.separator + puBlank + puOutFrame;
        }
        return url;
    }
  */

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


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

        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_TEAM_DIR);              // 出力ディレクトリ
//        String html_dir     = res.getString(RID_HTML_DIR);              // htmlディレクトリ
        String svg_dir      = res.getString(RID_PAGESVG_DIR);           // SVGディレクトリ

        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;      // テンプレートディレクトリ
        pr_svgDir      = project_dir + File.separator + svg_dir;        // SVGディレクトリ
    }


/**
  * 製作指示書の生成
  *
  * @param  Document    doc             ドキュメント
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean generateProduct(ProjectInfo project_info) throws Exception  {

        boolean ret = false;

        //Top Zone情報
        ZoneInfo zone_info = project_info.zone;

        String refresh;

        ret = productZone(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();
            ret = gr.generateRefresh(pr_templateDir, pr_outDir, refresh);
        }
        return ret;
    }

/**
  * 製作指示書　（ZONE)
  *
  * @param  ZoneInfo    zone            Zone情報
  * @param  ZoneInfo    parent          Zone情報の親
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean productZone(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 = productPage(zone, page_info);
                if (!ret) return false;
            }
        } else {
            //ページが存在しない場合は、Blankフレームを作成する
            productFrame( zone, null);
        }

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

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

/**
  * 製作指示書　(PAGE)
  *
  * @param  String      zone_name       Zone名（ディレクトリ）
  * @param  PageInfo    page_info       ページ情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean productPage(ZoneInfo zone, PageInfo page) throws RidException, Exception {

        boolean ret = false;

        // フレームの作成
        productFrame(zone, page);

        // ポンチ絵の生成
        generateProductSample(page);

        // ページ情報の生成
        generateProductInfo(page);

        // ページの生成(ここでは、ページ生成しない)
        //GeneratePage gp = new GeneratePage();
        //gp.generate(pr_htmlDir, pr_templateDir, pr_partsDir, zone, page);

        return true;
    }


/**
  * 製作指示書(フレーム)の生成
  *
  * @param  String      zone_name       Zone名（ディレクトリ）
  * @param  PageInfo    page_info       ページ情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean productFrame(ZoneInfo zone, PageInfo page) throws RidException, Exception  {
        boolean ret = false;
        xcopy xc = new xcopy();
        RidMessage ridMsg = new RidMessage();

        // _frameProduct.html有無判定
        String template = pr_templateDir + File.separator + puTemplProFrame;
        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 = generateFrameMapData(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" + mapper.getErrorString()));
        }

        return true;
    }

/**
  * データの生成（フレーム）
  *
  * @param  String      zone_name       Zone名
  * @param  PageInfo    page_info       ページ情報
  * @return Document    ドュメント
  */
    private Document generateFrameMapData(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 sample = page.name + puTemplSample;
            page_elem = xu.createSubElement(topElem, puMapFrameData);
			page_elem.setAttribute(puMapFrameDataKey, "sample");
//            attr = xu.createOrGetAttribute(page_elem, puMapFrameDataKey);
//            xu.createOrSetTextValue((Node)attr, "sample");
            xu.createOrSetTextValue(page_elem, puMapFrameInTag, sample);

            // ページ情報
            String info = page.name + puTemplInfo;
            page_elem = xu.createSubElement(topElem, puMapFrameData);

			page_elem.setAttribute(puMapFrameDataKey, "info");
//            attr = xu.createOrGetAttribute(page_elem, puMapFrameDataKey);
//            xu.createOrSetTextValue((Node)attr, "info");
            xu.createOrSetTextValue(page_elem, puMapFrameInTag, info);

            // メイン
            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  PageInfo    page            ページ情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean generateProductInfo(PageInfo page) throws RidException, Exception {

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

        //テンプレートファイル名
        String template = pr_templateDir + File.separator + puTemplInfo;
        if ( !xc.fileExists(template) ) {
            throw new RidException(ridMsg.Error("E4001",template));
        }

        //出力ファイル名
        String out = pr_outDir + File.separator + page.file + puOutInfo;

        // Map Dataの生成
        Document temp_data = generateInfoData(page);

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

        // ページ情報のHTML生成
        Mapper mapper = new Mapper();
        if(!mapper.Type2(template, temp_data, out)){
            throw new RidException(ridMsg.Error("E4002",mapper.getErrorString()));
        }
        return true;
    }



/**
  * データの生成（ページ情報）
  *
  * @param  PageInfo    page            ページ情報
  * @return Document    ドキュメント
  */
    private Document generateInfoData(PageInfo page_info) throws Exception {

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

        // 全属性を出力
        for ( int i = 0; i < page_info.attr_lst.size(); i++ ) {
            Attribute attr = (Attribute)page_info.attr_lst.elementAt(i);
            xu.createOrSetTextValue(topElem, attr.name, attr.value);
        }
        return doc;
    }


/**
  * 製作指示書(Sample)の生成
  *
  * @param  PageInfo    page            ページ情報
  * @return boolean     true（成功）/ false（失敗）
  */
    private boolean generateProductSample(PageInfo page) throws RidException, Exception {

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

        // SVGファイル有無
        if (!page.svg.equals("")) {
            // SVGファイルが指定されている場合、ファイルをコピーする
            String in  = pr_svgDir + File.separator + page.svg;
            String out = pr_outDir + File.separator + page.file + puOutSvg;
            ret = xc.file(in, out);
        } else if (!page.doc.equals("")) {
            // DOCファイルが指定されている場合、ファイルをコピーする
            String docfile = Document2SampleFile(page.doc);
            String in  = pr_svgDir + File.separator + docfile;
            String out = pr_outDir + File.separator + page.file + "_" + docfile;
            ret = xc.file(in, out);
        }

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

        // 出力ファイル名
        String out = pr_outDir + File.separator + page.file + puOutSample;

        // Map Dataの生成
        Document temp_data = generateSampleData(page);

        // ポンチ絵のHTML生成
        Mapper mapper = new Mapper();
        if ( !mapper.Type2(template, temp_data, out) ) {
          throw new RidException(ridMsg.Error("E4002",mapper.getErrorString()));
        }

        return true;
    }


/**
  * データの生成（Sample）
  *
  * @param  PageInfo    page            ページ情報
  * @return Document    ドキュメント
  */
    private Document generateSampleData(PageInfo page) throws Exception {

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

        xu.createOrSetTextValue(topElem, "Title", page.name + puTemplSample);

        //SVGの有無
        if (!page.svg.equals("")) {
            //SVGファイルあり
            xu.createOrSetTextValue(topElem, "sample", 
              "<embed src=\"" + page.name + puOutSvg + 
              "\" height=\"300\" width=\"400\" type=\"image/svg-xml\" pluginspage=\"http://www.adobe.com/svg/viewer/install/\">");
        } else if (!page.doc.equals("")) {
            //DOCファイルあり
            String docfile = Document2SampleFile(page.doc);

	    /* 2002/12/19
	       t3-nishimura@nri.co.jp added */
	    String docWithoutPath = trimPath(page.file + "_" + docfile);

            xu.createOrSetTextValue(topElem, "sample", 
	    /* 2002/12/19
	       t3-nishimura@nri.co.jp replaced */
		//"<a href=\"" + page.file + "_" + docfile + "\" target=\"_blank\">" + page.file + "_" + docfile + "</a>");
		"<a href=\"" + docWithoutPath + "\" target=\"_blank\">" + docWithoutPath + "</a>");
        } else {
            //SVG/DOCファイルなし
            xu.createOrSetTextValue(topElem, "sample", "<br><br><br><center> Now Thinking!</center>");
        }
       return doc;
    }

/**
  * PageUnitのDoc属性から製作指示書にコピーするドキュメントファイル名を求める（Sample）
  *
  * @param  String      docAttr         Doc属性
  * @return String      コピーするドキュメントファイル名を求める
  *
  *   ドキュメント編集用
  *     command.doc.app.n   = アプリケーション名
  *     command.doc.cmd.n   = アプリケーションコマンド
  *     command.doc.ext.n   = 拡張子
  *     command.doc.view.n  = 製作指示書用拡張子(省略可)
  */
    private String Document2SampleFile(String docAttr) throws Exception {

        String filename = docAttr;
        String command;

        // 拡張子を取得する
        String ext = getDocfileExt(docAttr);

        //リソースファイルからブラウザコマンドのリストを設定する
        ZResource res = ZApp.getTheApp().getResource();

        for ( int i = 1; ; i++ ) {
            command = "command.doc.ext." + Integer.toString(i);
            String  doc_ext = res.getString(command);
            // 拡張子の指定が無い場合終了
            if ( isNullString(doc_ext) ) break;

            // DOC属性のファイル名と同じ拡張子の場合

            // DOC属性のファイル名と拡張子を探す
            if (doc_ext.equalsIgnoreCase(ext)) {
                // DOC属性のファイル名と同じ拡張子の場合

                // 製作指示書用拡張子を取得する
                command = "command.doc.view." + Integer.toString(i);
                String  doc_view = res.getString(command);

                // nullは省略("")
                if ( !isNullString(doc_view) ) {
                    filename = getDocfileName(docAttr) + "." + doc_view;
                }
                break;
            } 
        }
        return filename;
  }

/**
  * ドキュメントファイル名を拡張子を求める（Sample）
  *
  * @param  String      docAttr         Doc属性
  * @return String      拡張子
  */
    private String getDocfileExt(String filename) throws Exception {

        String ext="";

        int pos = filename.indexOf(".");

        if (pos != -1) {
            ext = filename.substring(pos+1);
        }
        return ext;
    }
/**
  * ドキュメントファイル名をファイル名を求める（Sample）
  *
  * @param  String      docAttr         Doc属性
  * @return String      ファイル名
  */
    private String getDocfileName(String filename) throws Exception {

        String name=filename;

        int pos = filename.indexOf(".");

        if (pos != -1) {
            name = filename.substring(0,pos);
        }
        return name;
    }


    /**
     * ファイル名からパスをとり除いて返す
     *
     * @param fileName パスを取り除きたいファイル名
     * @return パスが取り除かれたファイル名
     * @author t3-nishimura@nri.co.jp
     */
    private String trimPath(String fileName){

	int pos = fileName.lastIndexOf("/");
	if (pos == fileName.length()) {
	    return "";
	}
	return fileName.substring(pos + 1);
    }
}
