/* $Id: RWRepository.java 1072 2016-02-27 04:27:27Z shayashi $ */
/*
 * �쐬��: 2006/06/02
 *
 */
package reasoning_web.logical;

import java.util.ArrayList;
import java.util.List;

import reasoning_web.logical.inter_face.RWElement;
import smart_gs.debugprint.Debugprint;
import smart_gs.image_search.normal.swingui.Observer;
import smart_gs.logical.GSResource;
import smart_gs.logical.Region;
import smart_gs.reasoning_web.logical.GSConnection;
import smart_gs.reasoning_web.logical.GSFactory;
import smart_gs.reasoning_web.logical.GSResourcePointer;
import smart_gs.reasoning_web.logical.GS_RWElement;
import smart_gs.reasoning_web.swingui.ReasoningWebFrame;
import smart_gs.swingui.WorkspaceWindow;


/**
 * @author kazuaki kobayashi
 * 
*/
public class RWRepository {
	
	protected List<GSResource> resourceBaskets;
	protected List<GSConnection> connections;
	protected List<ResourcePointer> pointers;
	private GSFactory factory;
	private List<Observer> observers;
	
	protected RWRepository(){
		this.factory = this.getFactory();
		this.connections = new ArrayList<GSConnection>();
		this.pointers = new ArrayList<ResourcePointer>();
		this.observers = new ArrayList<Observer>();
		this.resourceBaskets = new ArrayList<GSResource>();
	}
	public void initialize(){
		this.connections.clear();
		this.pointers.clear();
	}
	protected GSFactory getFactory() {
		return new GSFactory();
	}
	/**
	 * ResourcePointer of an element of RWElement is returned
	 * @param element
	 * @return
	 */
	public ResourcePointer getResourcePointer(RWElement element){
		for(int i=0;i<this.pointers.size();i++){
			GSResource tmp = this.pointers.get(i).getGSResource();
			if(tmp != null && tmp.equals(element)){
				return this.pointers.get(i);
			}
		}
		return null;
	}
	
	public boolean isRegistered(RWElement element){
		for(int i=0;i<this.pointers.size();i++){
			GSResource tmp = this.pointers.get(i).getGSResource();
			if(tmp != null && tmp.equals(element)){
				return true;
			}
		}
		return false;
	}
	
	public void createResourcePointer(GSResource elm){
		GSResourcePointer pointer;
		if(!this.isRegistered(elm)){
			pointer = (GSResourcePointer) factory.createResourcePointer(elm);
			this.register(pointer);
		}
	}
	
	
	/**
	 * source��target�Ԃ�connection���쐬����B
	 * note�͂���conneciton�ɕt������
	 * 
	 * @param source
	 * @param target
	 * @param note
	 */
	public void createConnection(GSResource source,GSResource target,
			ExplanatoryNote note){
		GSResourcePointer sourcePointer;
//		This makes a pointer unique to each element
		if(!this.isRegistered(source)){
			sourcePointer = (GSResourcePointer) factory.createResourcePointer(source);
			this.register(sourcePointer);
		}else{
			sourcePointer = (GSResourcePointer) this.getResourcePointer(source);
		}
		
		ResourcePointer targetPointer;
		if(!this.isRegistered(target)){
			targetPointer = this.factory.createResourcePointer(target);
			this.register(targetPointer);
		}else{
			targetPointer = this.getResourcePointer(target);
		}
		this.addConnection(sourcePointer, (GSResourcePointer) targetPointer, note);
		WorkspaceWindow.setUpdated(true);
	}

	public GSConnection getNewestConnection() {
		return connections.get(connections.size()-1);
	}
	protected void register(ResourcePointer pointer){
		if(!this.pointers.contains(pointer)){
			this.pointers.add(pointer);
		}
		this.notifyChange();
	}
	/**
	 * source��target�Ԃ�connection���쐬����B
	 * note�͂���conneciton�ɕt������
	 * 
	 * @param source
	 * @param target
	 * @param note
	 */
	private void addConnection(GSResourcePointer source,GSResourcePointer target,
			ExplanatoryNote note){
		this.connections.add(this.factory.createGSConnection(source, target, note));
//		ReasoningWebFrame.getInstance().reload();
	}

	protected void addConnection(GSConnection connection){
		this.connections.add(connection);
	}
	/**
	 * element�Ŏw�肳�ꂽResource��Reasoning Web�ɓo�^����
	 * @param element
	 */
	public void register(GSResource element){
		ResourcePointer pointer = this.factory.createResourcePointer(element);
		this.pointers.add(pointer);
		this.notifyChange();
	}
	/**
	 * element�Ŏw�肳�ꂽresource�������N���������ׂ�
	 * @param element
	 * @return 
	 */

	public boolean hasLink(RWElement element){
		ResourcePointer pointer = this.getResourcePointer(element);
		if(pointer == null){
			return false;
		}
		return pointer.hasLink();
	}

	public boolean hasLinkTarget(RWElement element){
		ResourcePointer pointer = this.getResourcePointer(element);
		if(pointer == null){
			return false;
		}
		return pointer.hasTarget();
	}

	public boolean hasLinkSource(RWElement element){
		ResourcePointer pointer = this.getResourcePointer(element);
		if(pointer == null){
			return false;
		}
		return pointer.hasSource();
	}
	
	public int getLinkType(RWElement element) {
		if (this.hasLinkTarget(element) && this.hasLinkSource(element)) {
			return ResourcePointer.BOTH;
		} else if (this.hasLinkSource(element)) {
			return ResourcePointer.IN;
		} else if (this.hasLinkTarget(element)) {
			return ResourcePointer.OUT;
		} else {
			return -1;
		}
	}

	
	
	/**
	 * ���ׂĂ�connection��Ԃ�
	 * @return
	 */
	public List<GSConnection> getConnections(){
		return this.connections;
	}
	/**
	 * ���ݓo�^����Ă��邷�ׂĂ�ResourcePointer��Ԃ�
	 * @return
	 */
	public List<ResourcePointer> getResourcePointers(){
		return this.pointers;
	}
	
	public List<RWElement> getDirectElements(ResourcePointer pointer){
		if(pointer == null){
			return null;
		}
		return pointer.getDirectLinkElements();
	}
	public void addObserver(Observer observer){
		this.observers.add(observer);
	}
	public void notifyChange(){
		for(int i=0;i<this.observers.size();i++){
			this.observers.get(i).update();
		}
	}

}
