/**
 * $Id: PageLinkTag.java,v 1.3 2006/01/30 15:22:25 rampil Exp $
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2004 satoshi akabane(akabane@logical-paradox.org)
 *
 */
package org.logical_paradox.kinako.taglib;

import java.io.IOException;
import java.text.MessageFormat;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;

/**
 * ページリンクタグ
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.3 $
 */
public class PageLinkTag extends TagSupport {
	/** シリアルバージョンUID */
	private static final long serialVersionUID = 5467322700104322509L;
	/** 1ページの表示件数 */
	private int num;
	/** 表示対象ページ */
	private int page;
	/** 検索結果の総件数 */
	private int hits;
	/** リンクを表示する件数 */
	private int range;

	/** リンク文字列 */
	private String href;

	/**
	 * タグ処理を開始する
	 * @return 終了コード
	 */
	@Override
	public int doStartTag() throws JspException {
		// 全部で何ページ分存在するか計算する
		int totalPages = hits / num;
		if(hits % num > 0) {
			totalPages++;
		}

		// 前後何ページ分のリンクを表示するか計算する
		int bgn = ((page-1) / range) * range;
		int end = totalPages - bgn < range ? totalPages : range;

		// 表示
		try {
			if(bgn > 1) {
				pageContext.getOut().write("<a href=\"" + buildURL(bgn) + "\">&lt;&lt;</a>&nbsp;");
			}
			for(int i = bgn +1; i <= end; i++) {
				if(i == page) {
					pageContext.getOut().write("<b>" + i + "</b>");
				} else {
					pageContext.getOut().write("<a href=\"" + buildURL(i) + "\">");
					pageContext.getOut().write(""+i);
					pageContext.getOut().write("</a>");
				}
				pageContext.getOut().write("&nbsp;");
			}
			if(end < totalPages) {
				pageContext.getOut().write("<a href=\"" + buildURL(end+1) + "\">&gt;&gt;</a>&nbsp;");
			}
			pageContext.getOut().flush();
		} catch (IOException e) {
			e.printStackTrace();
			throw new JspException(e.getMessage());
		}

		return SKIP_BODY;
	}

	/**
	 * URLを生成する
	 * @return 完成されたURL
	 */
	protected String buildURL(int pageNo) {
		return MessageFormat.format(href, "" + ((pageNo-1) * num));
	}
	/**
	 * 1ページの表示件数を返す
	 * @return 1ページの表示件数
	 */
	public String getNum() {
		return "" + num;
	}
	/**
	 * 1ページの表示件数を設定する
	 * @param i 1ページの表示件数
	 */
	public void setNum(String i) {
		Integer ii;
		try {
			ii =
				(Integer) ExpressionEvaluatorManager.evaluate(
					"num",
					i,
					Integer.class,
					this,
					pageContext);
			num = ii.intValue();
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 総件数を返す
	 * @return 総件数
	 */
	public String getHits() {
		return "" + hits;
	}

	/**
	 * 総件数を設定する
	 * @param i 総件数
	 */
	public void setHits(String i) {
		Integer ii;
		try {
			ii =
				(Integer) ExpressionEvaluatorManager.evaluate(
					"hits",
					i,
					Integer.class,
					this,
					pageContext);
			hits = ii.intValue();
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	/**
	 * ページ番号を返す
	 * @return ページ番号
	 */
	public String getPage() {

		return "" + page;
	}

	/**
	 * ページ番号を設定する
	 * @param i ページ番号
	 */
	public void setPage(String i) {
		Integer ii;
		try {
			ii =
				(Integer) ExpressionEvaluatorManager.evaluate(
					"page",
					i,
					Integer.class,
					this,
					pageContext);
			page = ii.intValue();
		} catch (JspException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 表示範囲を返す
	 * @return 表示範囲
	 */
	public String getRange() {
		return "" + range;
	}

	/**
	 * 表示範囲を設定する
	 * @param i 表示範囲
	 */
	public void setRange(String i) {
		Integer ii;
		try {
			ii =
				(Integer) ExpressionEvaluatorManager.evaluate(
					"range",
					i,
					Integer.class,
					this,
					pageContext);
			range = ii.intValue();
		} catch (JspException e) {
			e.printStackTrace();
		}
	}

	/**
	 * リンク先を設定する
	 * @param url リンク先
	 */
	public void setHref(String url) {
		try {
			href =
				(String) ExpressionEvaluatorManager.evaluate(
					"href",
					url,
					String.class,
					this,
					pageContext);
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	/**
	 * リンク先を返す
	 * @return リンク先
	 */
	public String getHref() {
		return href;
	}
}
