import java.awt.BasicStroke;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;

public class Links {
	private ArrayList<Link> list = null;

	public Links ( ){
		list = new ArrayList<Link>();
	}

	public void addLink(int origSerial, int endSerial, Point2D.Double p_orig, Point2D.Double p_end){
		list.add(new Link(origSerial, endSerial, p_orig, p_end));
	}

	public int getArrayListLength(){
		return list.size();
	}

	public Link getLink(int n){
		if(n>=0 && n<getArrayListLength()){
			return list.get(n);
		}
		else
			return null;
	}

	//あるノードに関連したリンクの端点の位置を変える(インクリメント版)
	public void incrementPositionOfRelatedLinks(int nodeSerial, double dx, double dy){
		for(int i=0; i<getArrayListLength(); i++){
			if(getLink(i).getOrigSerial() == nodeSerial)
				getLink(i).setPoint(0, getLink(i).getLine().x1+dx, getLink(i).getLine().y1+dy);
			else if(getLink(i).getEndSerial() ==nodeSerial)
				getLink(i).setPoint(1, getLink(i).getLine().x2+dx, getLink(i).getLine().y2+dy);
		}
	}

	//あるノードに関連したリンクの端点の位置を変える
	public void setPositionOfRelatedLinks(int nodeSerial, double x, double y){
		for(int i=0; i<getArrayListLength(); i++){
			if(getLink(i).getOrigSerial() == nodeSerial)
				getLink(i).setPoint(0, x, y);
			else if(getLink(i).getEndSerial() ==nodeSerial)
				getLink(i).setPoint(1, x, y);
		}
	}

	//あるノードに関連したリンクを削除する
	public void deleteRelatedLinks(int nodeSerial){
		for(int i=getArrayListLength()-1; i>=0; i--){
			if(getLink(i).getOrigSerial()==nodeSerial || getLink(i).getEndSerial()==nodeSerial){
				list.remove(i);
			}
		}
	}

	// マウスでクリックしているノードのIDを返す．どこにも触っていないときは-1を返す．
	public int getTouchedLinkID(double x, double y){
		int ret = -1;
		for(int i=0; i<getArrayListLength(); i++){
			if(getLink(i).getShape().contains(x, y)){
				ret = i;
			}
		}
		return ret;
	}

	public void deleteLink(int id){
		list.remove(id);
	}
}


class Link {
	private Line2D.Double link = null;
	private boolean isSelected = false;
	private int origSerial = -1;
	private int endSerial = -1;
	private int origID = -1;
	private int endID = -1;
	private Shape shape = null;
	private Stroke stroke = new BasicStroke(3); //マウスによるクリック判定のために少し太さをもたせる
	private int back_fwd = 0; //リンク順方向の後進指定 あり 1, なし 0
	private int back_bwd = 0; //リンク逆方向の後進指定 あり 1, なし 0

	public Link(int origserial, int endserial, Point2D.Double p_orig, Point2D.Double p_end){
		link = new Line2D.Double(p_orig, p_end);
		origSerial = origserial;
		endSerial = endserial;
	}


	public Line2D.Double getLine(){
		return link;
	}

	//マウスによるクリック判定のためのShapeオブジェクトを返す
	public Shape getShape(){
		shape  = stroke.createStrokedShape(link);
		return shape;
	}

	// flagが0のときは始点を変更．1のときは終点を変更
	public void setPoint(int flag, double x, double y){
		if(flag==0)
			link.setLine(x, y, link.x2, link.y2);
		else
			link.setLine(link.x1, link.y1, x, y);
	}

	public void setPoints(double x1, double y1, double x2, double y2){
		link.setLine(x1, y1, x2, y2);
	}

	public boolean getIsSelected(){
		return isSelected;
	}

	public void setSelected(boolean val){
		isSelected = val;
	}

	public void flipSelected(){
		if(isSelected==true)
			isSelected = false;
		else
			isSelected = true;
	}

	public int getOrigSerial(){
		return origSerial;
	}

	public int getEndSerial(){
		return endSerial;
	}

	public void setOrigID(int id){
		origID = id;
	}

	public void setEndID(int id){
		endID = id;
	}

	public int getOrigID(){
		return origID;
	}

	public int getEndID(){
		return endID;
	}

	public void setBackFWD(int flag){
		back_fwd = flag;
	}

	public void setBackBWD(int flag){
		back_bwd = flag;
	}

	public int getBackFWD(){
		return back_fwd;
	}

	public int getBackBWD(){
		return back_bwd;
	}

}
