/*
 * Created on 2003/05/11
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.j69.eewiki.wiki;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Vector;

import org.j69.eewiki.util.CacheConfig;
import org.j69.eewiki.util.ExtensionFilter;
import org.j69.eewiki.util.UtilComparator;

/**
 * @author sally
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class WikiList {

	// コンフィグ
	private final static CacheConfig config_ = CacheConfig.getInstance( );

	private String wikidir_;

	/**
	 * コンストラクタ 
	 */
	public WikiList(String wikidir) {
		wikidir_ = wikidir;
	}

	/**
	 * 対象ファイル一覧取得
	 * @param seachText
	 * @return
	 */
	public Vector getWikiFiles(String seachText) {
		Vector dataFiles = getContentsFileList(new File(wikidir_));
		if(seachText == null || seachText.equals("")) {
			return dataFiles;
		} else {
			return grep(dataFiles, seachText);
		}
	}

	/**
	 * 対象ファイル一覧取得
	 * @param seachText
	 * @param sortType
	 * @return
	 */
	public Vector getWikiFiles(String seachText, String sortType) {
		Vector dataFiles = getContentsFileList(new File(wikidir_));
		
		// ベクターから配列へ...toArrayの使い方把握して直すこと
		WikiFile[] wikiFiles = new WikiFile[dataFiles.size()];
		int i = 0;
		for(Iterator it = dataFiles.iterator(); it.hasNext();){
			wikiFiles[i] = (WikiFile)it.next();
			i++;			
		}
		
		// 一覧のソート
		final UtilComparator wikiComparator;
		if(sortType.equals("title")) {
			wikiComparator = new TitleComparator("ASC");
		} else {
			wikiComparator = new DateComparator("DESC");
		}
		Arrays.sort(wikiFiles, wikiComparator);
		Vector sortData = new Vector();
		for(int j=0; j<wikiFiles.length;j++) {
			sortData.add(wikiFiles[j]);
		}
		
		if(seachText == null || seachText.equals("")) {
			return sortData;
		} else {
			return grep(sortData, seachText);
		}
	}

	/**
	 * 添付ファイル一覧取得
	 * @param seachText
	 * @param sortType
	 * @return
	 */
	public Vector getAttFiles(String seachText, String sortType) {
		Vector dataFiles = getAttachmentList(new File(wikidir_));
		
		// ベクターから配列へ...toArrayの使い方把握して直すこと
		WikiFile[] wikiFiles = new WikiFile[dataFiles.size()];
		int i = 0;
		for(Iterator it = dataFiles.iterator(); it.hasNext();){
			wikiFiles[i] = (WikiFile)it.next();
			i++;			
		}
		
		// 一覧のソート
		final UtilComparator wikiComparator;
		if(sortType.equals("title")) {
			wikiComparator = new TitleComparator("ASC");
		} else {
			wikiComparator = new DateComparator("DESC");
		}
		Arrays.sort(wikiFiles, wikiComparator);
		Vector sortData = new Vector();
		for(int j=0; j<wikiFiles.length;j++) {
			sortData.add(wikiFiles[j]);
		}
		
		if(seachText == null || seachText.equals("")) {
			return sortData;
		} else {
			return grep(sortData, seachText);
		}
	}

	/**
	 * @param dataFiles
	 * @param seachText
	 * @return
	 */
	private Vector grep(Vector dataFiles, String seachText) {
		
		Vector destDataFiles = new Vector();
		for(Iterator it = dataFiles.iterator(); it.hasNext();){
			WikiFile wikifile = (WikiFile)it.next();
			File file = new File(wikifile.getContentsPath());
			if(find(file, seachText)) {
				destDataFiles.add(wikifile);
			}
		}
		dataFiles.clear();
		return destDataFiles;
	}

	/**
	 * 指定ファイル内のテキストを検索と判定。
	 * ファイル内の文字列・ファイル名にtext含む場合trueを返します。
	 * @param file ファイル
	 * @param text 検索文字列
	 * @return boolean 対象文字列を含むファイルならtrue, それ以外はfalse
	 * @throws IOException
	 */
	public static boolean find(File file, String text) {
		// ファイル名に対象文字列が含まれていたらtrue
		if(find(file.getName(), text)) return true;
		
		boolean flg = false;
		try {
			flg = find(new InputStreamReader(new FileInputStream(file), 
				WikiConstants.DEFAULT_FILE_ENCODING), text);
		
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		
		return flg;
	}
	/**
	 * 指定リーダ内のテキストを検索と判定。
	 * リーダ内の文字列にtext含む場合trueを返します。
	 * @param reader リーダ
	 * @param text 検索文字列
	 * @return boolean 対象文字列を含めばtrue, それ以外はfalse
	 * @throws IOException
	 */
	public static boolean find(Reader reader, String text) throws IOException {

		if(text == null || text.equals("")) return false;
		
		BufferedReader in = null;
		try {
			in = new BufferedReader(reader);
			String str = null;
			while((str = in.readLine()) != null) {
				if(find(str, text)) return true;
			}
		} finally {
			if(in != null) { in.close(); }
		}
		return false;
	}
	/**
	 * 文字列strにtextを含無かどうかの判定。
	 * @param str 文字列
	 * @param text 検索文字列
	 * @return boolean true - textを含む, false - textを含まない。
	 */
	public static boolean find(String str, String text) {
		return find(str, text, true);
	}
	/**
	 * 文字列strにtextを含無かどうかの判定。
	 * @param str 文字列
	 * @param text 検索文字列
	 * @param flg 大文字・小文字を区別しないかどうか true=区別しない,false=区別する
	 * @return boolean true - textを含む, false - textを含まない。
	 */
	public static boolean find(String str, String text, boolean flg) {
		if(text == null || text.equals("")) return false;

		if(flg) {
			if(str.toUpperCase().indexOf(text.toUpperCase()) != -1) 
				return true;
			else 
				return false;
		} else {		
			if(str.indexOf(text) != -1) 
				return true;
			else 
				return false;
		}
	}

	/**
	 * Wikiベースディレクトリ以下のWikiページオブジェクトをVectorに格納する
	 *  
	 */
	private Vector getContentsFileList(File dir){

		// データファイル拡張子をフィルタ定義
		ExtensionFilter filter = new ExtensionFilter();
		filter.addExtension(WikiConstants.WIKI_DATA_EXTANSION);

		Vector oFileLists = new Vector();
		if(dir.isDirectory()){
			// 内部の一覧を取得
			File[] oFiles = dir.listFiles(filter);
			for(int i=0; i<oFiles.length; i++) {
				if(oFiles[i].isDirectory()){
					// 再帰的にコールして配下のデータを取得
					Vector ssFiles = this.getContentsFileList(oFiles[i]);
					for(Iterator it = ssFiles.iterator(); it.hasNext();){
						oFileLists.add(it.next());
					}
				} else {
					WikiFile wikifile = new WikiFile(oFiles[i].getName());
					oFileLists.add(wikifile);
				}
			}
		}
		return oFileLists;
	}

	/**
	 * Wikiベースディレクトリ以下のWikiページオブジェクトをVectorに格納する
	 *  添付ファイル用
	 */
	private Vector getAttachmentList(File dir){

		// 添付ファイル拡張子をフィルタ定義
		ExtensionFilter attfilter = new ExtensionFilter();
		String[] suffixs = config_.getConfigArray ("define.upload.suffix");
		for (int i = 0; i < suffixs.length; i++) {
			if (!suffixs[i].equals("*"))
				attfilter.addExtension(suffixs[i]);
		}
		
		Vector oFileLists = new Vector();
		if(dir.isDirectory()){
			// 内部の一覧を取得
			File[] oFiles = dir.listFiles(attfilter);
			for(int i=0; i<oFiles.length; i++) {
				if(oFiles[i].isDirectory()){
					// 再帰的にコールして配下のデータを取得
					Vector ssFiles = this.getAttachmentList(oFiles[i]);
					for(Iterator it = ssFiles.iterator(); it.hasNext();){
						oFileLists.add(it.next());
					}
				} else {
					WikiFile wikifile = new WikiFile(oFiles[i].getName());
					oFileLists.add(wikifile);
				}
			}
		}
		return oFileLists;
	}

}
