package jp.ac.dendai.im;

import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * フィードの item 要素
 */
public class Item implements Comparable<Item>{
	/** title要素 */
	private String title;
	/** link要素 */
	private String link;
	/** description要素 */
	private String description;
	/** dc:date要素 */
	private String dcDate;
	/** pubDate要素 */
	private String pubDate;
	/** Java の形式に変換した日付 */
	private Date date;
	/**
	 *  コンストラクタ
	 *  @param title タイトル
	 *  @param link リンク
	 *  @param description 説明の文章
	 *  @param dcDate 投稿日時(RSS 1.0)
	 *  @param pubDate 投稿日時(RSS 2.0)
	 */
	public Item(String title, String link, String description, String dcDate, String pubDate) {
		this.title = title;
		this.link = link;
		this.description = description;
		this.dcDate = dcDate;
		this.pubDate = pubDate;
		if(dcDate != null && !dcDate.equals("")) {
			date = rfc3339toDate(dcDate);
		}
		else if(pubDate != null && !pubDate.equals("")) {
			date = pubDate2Date(pubDate);
		}
	}
	/**
	 *  title要素の内容である item のタイトルを返す
	 *  @return タイトル
	 */
	public String getTitle() {
		return title;
	}
	/**
	 *  link要素の内容である URL を文字列で返す
	 *  @return リンク先のURL
	 */
	public String getLink() {
		return link;
	}
	/**
	 *  description要素の内容である説明の文章を返す
	 *  @return 説明の文章
	 */
	public String getDescription() {
		return description;
	}
	/**
	 *  dc:date要素(RSS 1.0)の内容である投稿日時を返す
	 *  @return 投稿日時
	 */
	public String getDCDate() {
		return dcDate;
	}
	/**
	 *  pubDate要素(RSS 2.0)の内容である投稿日時を返す
	 *  @return 投稿日時
	 */
	public String getPubDate() {
		return pubDate;
	}
	/**
	 *  投稿日時を返す
	 *  @return 投稿日時を表す Date インスタンス
	 */
	public Date getDate() {
		return date;
	}
	/**
	 *  RFC3339形式の日時 (dc:date 要素, updated 要素) を Date に変換
	 *  @param rfc3339 RFC3339形式の日時 (dc:date 要素, updated 要素)
	 *  @return Dateインスタンス
	 */
	private Date rfc3339toDate(String rfc3339) {
		// 先頭が数字でなければ RFC3339 ではない
		if(rfc3339.charAt(0) - '0' > 9)
			return pubDate2Date(rfc3339);
		// 大文字にし、UTC の省略記法である Z を +00:00 に変換
		rfc3339 = rfc3339.toUpperCase(Locale.ENGLISH).replace("Z", "+00:00");
		// TimeZone の ':' を削除
		int colon = rfc3339.lastIndexOf(':');
		rfc3339 = rfc3339.substring(0, colon) + rfc3339.substring(colon + 1, rfc3339.length());
		// ミリ秒を削除
		if(rfc3339.indexOf('.') != -1)
			rfc3339 = rfc3339.replaceAll("\\.\\d+", "");
		// 秒がなかったら :00 を付加 (価格.com対策)
		if(rfc3339.indexOf('+') != 19)
			rfc3339 = rfc3339.replace("+", ":00+");
		String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
		SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US);
		return format.parse(rfc3339, new ParsePosition(0));
	}
	/**
	 *  pubDate 要素の内容を Date に変換
	 *  @param pubDate pubDateの内容
	 *  @return Dateインスタンス
	 */
	private Date pubDate2Date(String pubDate) {
		String pattern = "EEE, dd MMM yyyy HH:mm:ss Z";
		SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US);
		return format.parse(pubDate, new ParsePosition(0));
	}
	/**
	 *  Itemを投稿日時で比較
	 *  @param anotherItem 比較対象の Item
	 *  @return 順序の整数表現 (自分が前なら負の値・後なら正の値)
	 */
	public int compareTo(Item anotherItem) {
		return this.date.compareTo(anotherItem.getDate());
	}
	/**
	 *  この item 要素の文字列表現を返す
	 *  @return この item 要素の文字列表現
	 */
	@Override
	public String toString() {
		return "title: " + title + "\nlink: " + link + "\ndescription: " + description +
				"\ndate: " + DateFormat.getDateTimeInstance().format(date);
	}
}
