/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.io;

import org.opengion.fukurou.util.StringUtil;

import org.jfree.chart.urls.CategoryURLGenerator;
import org.jfree.chart.urls.PieURLGenerator;
import org.jfree.chart.urls.XYURLGenerator;

import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.data.xy.XYDataset;

/**
 * A URL generator that can be assigned to a
 * {@link org.jfree.chart.renderer.category.CategoryItemRenderer}.
 */
public class HybsURLGenerator implements CategoryURLGenerator, PieURLGenerator, XYURLGenerator {

	/** The prefix. */
	private final String prefix ;

	/** The category parameter name. */
	private String categoryName = "category";

	/** The pie index parameter name. */
	private String indexName = "pieIndex";

	/** Series parameter name to go in each URL */
	private String seriesName = "series" ;

	/**
	 * クリッカブル・マップ用URLを指定します。
	 *
	 * 画像に、クリッカブル・マップを作成する場合の、URL を指定します。
	 * これは、画像上にエリア指定でリンク引数を作成することが可能です。
	 * URL 自身は、? 付きで固定値の引数を連結することが可能です。
	 * クリックしたエリアのカテゴリやインデックスの値(引数)は、自動的に
	 * 設定されます。(指定しない場合はチャートによって異なります)
	 * ※ 本家 jFreeChart とは並び順やキーが異なります。
	 * <pre>
	 * ・Pie      ：category、pieIndex
	 * ・XY       ：category、series
	 * ・Category ：category、series
	 * </pre>
	 * この引数の URL の名称を変更したい場合は、URL に続けて、カンマ(,) で、
	 * 名称を記述してください。
	 * 例：link.jsp,BLOCK
	 *
	 * @param	imageMapUrl	クリッカブル・マップ用URL
	 */
	public HybsURLGenerator( final String imageMapUrl ) {
		boolean first = imageMapUrl.indexOf( '?' ) < 0 ;	// 含まなければ true

		int adrs = imageMapUrl.indexOf( ',' );
		if( adrs < 0 ) {	// 引数が ０個
			prefix = imageMapUrl + ( first ? "?" : "&" );
		}
		else {
			// 一番目の引数設定
			prefix = imageMapUrl.substring( 0,adrs ) + ( first ? "?" : "&" ) ;
			int adrs2 = imageMapUrl.indexOf( ',',adrs+1 );
			if( adrs2 < 0 ) {	// 引数が 1個確定
				categoryName = imageMapUrl.substring( adrs+1 );
			}
			else {
				categoryName = imageMapUrl.substring( adrs+1,adrs2 );
				seriesName   = imageMapUrl.substring( adrs2+1 );
				indexName    = seriesName;
			}
		}
	}

	/**
	 * Generates a URL for a particular item within a series.
	 *
	 * @param	dataset		カテゴリDataset
	 * @param	series		シリーズ番号
	 * @param	category	カテゴリ番号
	 *
	 * @return	作成されたURL文字列
	 */
	public String generateURL( final CategoryDataset dataset, final int series, final int category ) {
		Comparable<?> seriesKey   = dataset.getRowKey(series);			// 4.3.3.6 (2008/11/15) Generics警告対応
		Comparable<?> categoryKey = dataset.getColumnKey(category);		// 4.3.3.6 (2008/11/15) Generics警告対応

		String url = prefix
						+ categoryName + "="
						+ StringUtil.urlEncode(categoryKey.toString() )
						+ "&" + seriesName + "="
						+ StringUtil.urlEncode( seriesKey.toString() );
		return url;
	}

	/**
	 * Generates a URL.
	 *
	 * @param	dataset		パイDataset
	 * @param	key			アイテムキー
	 * @param	pieIndex	インデックス番号
	 *
	 * @return	作成されたURL文字列
	 */
	@SuppressWarnings("rawtypes")
	public String generateURL( final PieDataset dataset, final Comparable key, final int pieIndex ) {
		String url = prefix
						+ categoryName + "="
						+ StringUtil.urlEncode(key.toString() )
						+ "&" + indexName + "="
						+ pieIndex;

		return url;
	}

	/**
	 * Generates a URL for a particular item within a series.
	 *
	 * @param	dataset		エックスワイDataset
	 * @param	series		シリーズ番号
	 * @param	item		アイテム番号
	 *
	 * @return	作成されたURL文字列
	 */
	public String generateURL( final XYDataset dataset, final int series, final int item ) {
		String url = prefix
						+ categoryName + "=" + item
						+ "&" + seriesName + "=" + series;
		return url;
	}
}
