/*
 * @(#)GenerateSiteMap.java
 *
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 *
 * RID-X : Generator サイトマップ生成
 *
 * @author  Intelligent Technology Inc.
 * @version 1.01 2002/02/19
 */
package jp.co.nri.rid.generator;

import java.io.*;
import java.util.*;

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.error.*;
import jp.co.nri.rid.snapshot.*;

/**
 * Rid サイトマップ生成
 */
public class GenerateSiteMap extends GenerateParser {

    /** テンプレートディレクトリ  **/
    protected String pr_templateDir;
    /** 出力ディレクトリ **/
    protected String pr_outDir;
    /** htmlディレクトリ  **/
    protected String pr_htmlDir;
    /** インデント  **/
    protected String pr_tab = "  ";
    /** URL **/
    protected String pr_url;


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


/**
  * サイトマップ生成
  *
  * @param  Document    doc             ドキュメント
  * @param  String      project_dir     プロジェクトディレクトリ
  * @param  String      header_file     ヘッダファイル
  * @param  String      footer_file     フッターファイル
  */
    public boolean generate(Document doc, String project_dir, String header_file,  String footer_file) throws Exception {

        boolean ret = false;

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

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

        //サイトマップの生成
        ret = generateSiteMap(project_info, header_file, footer_file);

        return true;
    }


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


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


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

        ZResource res = ZApp.getTheApp().getResource();
        String template_dir = res.getString("rid.template.dir");        // テンプレートディレクトリ
//        String html_dir     = res.getString("rid.html.dir");            // htmlディレクトリ

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


/**
  * サイトマップの生成
  *
  * @param  ProjectInfo project_info    プロジェクト情報
  * @param  String      header          ヘッダのファイル名
  * @param  String      footer          フッダのファイル名
  * @return void
  */
    private boolean generateSiteMap(ProjectInfo project_info, String header, String footer) throws Exception {

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

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

        // 出力ファイル名
        String out = pr_htmlDir + File.separator + puOutSitemap;

        // ZONEリストの作成
        ZoneInfo zone_info = project_info.zone;
        String zoneList = "<ul>\n" + sitemapZoneMap(zone_info) + "</ul> \n";

        // サイトマップの作成
        String siteMap = sitemapZoneInfo(zone_info, 0);

        // ヘッダファイルを読込む
        String headerString = filname2String(pr_templateDir + File.separator + header);

        // フッタファイルを読込む
        String footerString = filname2String(pr_templateDir + File.separator + footer);

        //データの生成
        Document temp_data = sitemapData(zoneList, siteMap, headerString, footerString);

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

        // Urlを設定
        setUrl(replaceWebFileSeparator(out));
        
        return ret;
    }

/**
  * Zoneリストを作成
  *
  * @param  ZoneInfo    zone            ZONE情報
  * @return String      Zoneリストの文字列
  */
    private String sitemapZoneMap(ZoneInfo zone) throws Exception {

        String zoneMap = "";
        zoneMap = "<li><a href=\"#" + zone.file + "\">" + zone.title + "(" + zone.name + ")</a>\n\r";
        //Zone情報
        for ( int n = 0; n < zone.zone_lst.size(); n++ ) {
            ZoneInfo zone_info = (ZoneInfo)zone.zone_lst.elementAt(n);
            zoneMap = zoneMap + sitemapZoneMap(zone_info);
        }
        return zoneMap;
    }


/**
  * サイトマップの作成
  *
  * @param  ZoneInfo    zone            ZONE情報
  * @param  int         itag            タグ情報
  *
  * ZONEの単位で繰り返し
  *
  *   <ul> ZONEタイトル(ZONE名)
  *     <li><a href="Page1"> PAGE1タイトル(Page1名)
  *     <li><a href="Page2"> PAGE2タイトル(Page2名)
  *     .....
  *   </ul>
  *
  *
  * @return String      サイトマップの文字列
  */
    private String sitemapZoneInfo(ZoneInfo zone, int itag) throws Exception {

        String siteMap = "\n";

        siteMap = "<a name=\"#" + zone.file + "\"></a>\n" +  tagString(itag) + "<ul> " + zone.title + "(" + zone.name + ")\n\r";

        //Page情報
        for ( int i = 0; i < zone.page_lst.size(); i++ ) {
            PageInfo page_info = (PageInfo)zone.page_lst.elementAt(i);
            siteMap = siteMap + sitemapPageInfo(page_info, itag);
        }

        //Zone情報
        for ( int n = 0; n < zone.zone_lst.size(); n++ ) {
            ZoneInfo zone_info = (ZoneInfo)zone.zone_lst.elementAt(n);
            siteMap = siteMap + sitemapZoneInfo(zone_info, itag + 1);
        }

        siteMap = siteMap + tagString(itag) + "</ul>\n";

        return siteMap;
    }


/**
  * ページの情報を作成
  *
  * @param  PageInfo    page_info       PAGE情報
  * @param  int         itag            タグ情報
  *
  * この部分
  *     <li><a href="Page1"> PAGE1タイトル(Page1名)
  *
  * @return String      ページ情報の文字列
  */
    private String sitemapPageInfo(PageInfo page_info, int itag) throws Exception {

        String name  = page_info.name;
        String file  = page_info.file;
        String title = page_info.title;

        return (tagString(itag + 1) + "<li><a href=\"" + file + "\">" + title + " (" + name + ")</a>\n\r");
    }

/**
  * タグの空白文字列作成
  *
  * @param  int         itag            タグ数
  * @return String      空白文字列
  */
    private String tagString(int itag) throws Exception {

        String tagString = "";

        for ( int i = 0; i < itag; i++ ) {
            tagString = tagString + pr_tab;
        }
        return tagString;
    }

/**
  * サイトマップのデータ生成
  *
  * @param  String      page_name       ページの名前
  * @return Document    ページのドュメント
  */
    private Document sitemapData(String zonemap, String sitemap, String header, String footer) 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, "zonemap", zonemap);
        xu.createOrSetTextValue(topElem, "sitemap", sitemap);
        xu.createOrSetTextValue(topElem, "header", header);
        xu.createOrSetTextValue(topElem, "footer", footer);
        return doc;

    }


/**
  * 指定されたファイルの内容をString型に変換する
  *
  * @param  String      file_name       ファイル名
  * @return String      ファイルの内容
  */
    private String filname2String(String file_name)  throws Exception  {

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

        //ファイルの存在確認
        ret = xc.fileExists(file_name);
        if (ret) {
            char str[]=new char[256];
            FileInputStream inFileStream = new FileInputStream(file_name);
            InputStreamReader InData=new InputStreamReader(inFileStream);
            while ((InData.read(str, 0, 1)) != -1) {
              fileString = fileString + str[0];
            }
            InData.close();
        } else {
             ZDebug.trace(ridMsg.Warning("W4002",file_name));
        }
        return fileString;
   }

}
