package jp.ac.kyutech.mns.ist.play;

import java.awt.geom.Point2D;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import jp.ac.kyutech.mns.ist.ShortStroke;
import edu.umd.cs.piccolo.util.PBounds;

/**
 * ShortStrokeを束ねて保持するためのクラス．NoteがShortStrokeを保持・管理するために使用する．
 * 
 * @author miuramo
 * 
 */
public class ShortStrokeHolder extends TreeSet<ShortStroke> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 7990477191854915087L;

	transient Hashtable<Long, ShortStroke> hash;

	// TreeSet はオブジェクトを持っているかどうか？は教えてくれる(contains)が，
	// そのオブジェクトだけを簡単に返してくれるメソッドがない．
	// (subSetで帰ってくるものから取り出せば良いのかもしれないが)
	// なので，hashを用意した．どちらにせよ，時刻timeで簡単にとりだすには
	// こうするほうがよいと思う．

	transient Hashtable<String, SortedSet<ShortStroke>> temphash; // 一時的に，ある範囲の座標を保存しておきたいときにつかう

	public String backstrid;

//	public String backmac;

	public ShortStrokeHolder() {
		super(ShortStrokeHolderComparator.defaultShortStrokeComparator);
		hash = new Hashtable<Long, ShortStroke>();
		temphash = new Hashtable<String, SortedSet<ShortStroke>>();
	}

	public void setIDs(String num) {
//		backmac = new String(mac);
		backstrid = new String(num);
	}

	public void addSS(ShortStroke ss) {
		this.add(ss);
		hash.put(ss.time, ss);
		// System.out.println("Holder: addstroke "+ this.size() + "
		// "+hash.size());
	}

	public ShortStroke getSS(long t) {
		return hash.get(t);
	}

	public SortedSet<ShortStroke> tailSS(ShortStroke ss) {
		TreeSet<ShortStroke> ts = new TreeSet<ShortStroke>(
				ShortStrokeHolderComparator.defaultShortStrokeComparator);
		return ts.tailSet(ss);
	}

	public SortedSet<ShortStroke> headSS(ShortStroke ss) {
		TreeSet<ShortStroke> ts = new TreeSet<ShortStroke>(
				ShortStrokeHolderComparator.defaultShortStrokeComparator);
		return ts.headSet(ss);
	}

	public SortedSet<ShortStroke> subSetSS(ShortStroke s1, ShortStroke s2) {
		TreeSet<ShortStroke> ts = new TreeSet<ShortStroke>(
				ShortStrokeHolderComparator.defaultShortStrokeComparator);
		return ts.subSet(s1, s2);
	}

	public SortedSet<ShortStroke> tailSSLong(long l) {
		TreeSet<ShortStroke> ts = new TreeSet<ShortStroke>(
				ShortStrokeHolderComparator.defaultShortStrokeComparator);
		return ts.tailSet(hash.get(l));
	}

	public SortedSet<ShortStroke> headSSLong(long l) {
		TreeSet<ShortStroke> ts = new TreeSet<ShortStroke>(
				ShortStrokeHolderComparator.defaultShortStrokeComparator);
		return ts.headSet(hash.get(l));
	}

	public SortedSet<ShortStroke> subSetSSLong(long l1, long l2) {
		TreeSet<ShortStroke> ts = new TreeSet<ShortStroke>(
				ShortStrokeHolderComparator.defaultShortStrokeComparator);
		return ts.subSet(hash.get(l1), hash.get(l2));
	}

	public SortedSet<ShortStroke> currentRegionSetSS(PBounds region,
			boolean includeIntersects) {
		TreeSet<ShortStroke> ts = new TreeSet<ShortStroke>(
				ShortStrokeHolderComparator.defaultShortStrokeComparator);
		// ShortStrokeBoundsFilter ssbf = new ShortStrokeBoundsFilter(region);
		Iterator<ShortStroke> ite = this.iterator();
		while (ite.hasNext()) {
			ShortStroke ss = ite.next();
			PBounds b = ss.getBounds();
			// System.out.println(b.toString());
			if (includeIntersects) {
				if (region.contains(b) || region.intersects(b)) {// 基準boundsが，arpを含むか，もしくは重なっている場合
					ts.add(ss);
				}
			} else {
				if (region.contains(b)) {// 基準boundsが，arpを含む場合
					ts.add(ss);
				}
			}
		}
		return ts;
	}

	// 一括して透明度変更
	public void setTransparencyForRange(float f, ShortStroke s1, ShortStroke s2) {
		Iterator<ShortStroke> ite = subSetSS(s1, s2).iterator();
		while (ite.hasNext()) {
			ite.next().setTransparency(f);
		}
	}

	// 全部透明度変更
	public void setTransparencyForAll(float f) {
//		System.out.println("vector size" + this.size());
		Iterator<ShortStroke> ite = this.iterator();
		while (ite.hasNext()) {
			ite.next().setTransparency(f);
		}
	}

	// 選択部分を保存
	public void keepRange(ShortStroke s1, ShortStroke s2, String key) {
		temphash.put(key, subSetSS(s1, s2));
	}

	// 保存した部分を取り出す
	public SortedSet<ShortStroke> getRange(String key) {
		return temphash.get(key);
	}

	// 指定した座標に含まれるものを探す（StudentPanelにもあり）
	public SortedSet<ShortStroke> getCloseSS(Point2D p) {
		return null;
	}

}

/**
 * ShortStrokeの時間順コンパレータ
 * @author miuramo
 *
 */
class ShortStrokeHolderComparator {
	public static Comparator<ShortStroke> defaultShortStrokeComparator = new Comparator<ShortStroke>() {

		public int compare(ShortStroke arg0, ShortStroke arg1) {
			return (int) (arg0.time - arg1.time);
		}

		public boolean equals(Object o1) {
			return false;
		}
	};
}

// class ShortStrokeBoundsFilter implements PNodeFilter{
// PBounds bounds; // 判定する領域
// public ShortStrokeBoundsFilter(PBounds r){
// bounds = r;
// }
// public boolean accept(PNode aNode){
// System.out.println(aNode.getBoundsReference().toString());
// if (bounds.contains(aNode.getBoundsReference())||
// bounds.intersects(aNode.getBoundsReference())){//基準boundsが，arpを含むか，もしくは重なっている場合
// return true;
// }
// return false;
// }
// public boolean acceptChildrenOf(PNode aNode){
// return true;
// }
// }
