/* $Id: GS_RWRepository.java 1072 2016-02-27 04:27:27Z shayashi $ */
/*
 * ????: 2006/06/02
 *
 */
package smart_gs.reasoning_web.logical;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import reasoning_web.logical.Connection;
import reasoning_web.logical.Factory;
import reasoning_web.logical.RWRepository;
import reasoning_web.logical.ResourcePointer;
import reasoning_web.logical.inter_face.RWElement;
import smart_gs.logical.GSResource;
import smart_gs.logical.Region;
import smart_gs.logical.ResourceBasket;
import smart_gs.logical.URIObject;
import smart_gs.reasoning_web.desktop.swingui.ReasoningWebDesktop;
import smart_gs.reasoning_web.swingui.LocalViewFrame;
import smart_gs.swingui.ResourceBasketsFrame;
import smart_gs.swingui.WorkspaceWindow;
import smart_gs.util.GSLog;
import smart_gs.util.Quadruple;

/**
 * @author kazuaki kobayashi
 * 
 */
public class GS_RWRepository extends RWRepository {

	private static GS_RWRepository singleton = new GS_RWRepository();
	
	//20090422 North Grid
	private String backgroundFilePath = null;

	private GS_RWRepository() {
		super();
	}

	public static GS_RWRepository getInstance() {
		return singleton;
	}

	@Override
	protected GSFactory getFactory() {
		return new GSFactory();
	}

	public ArrayList<Quadruple<Connection, GSResourcePointer, GSExplanatoryNote, Integer>> 
	  getLocalViewInfo(GS_RWElement element) {
		return ((GSResourcePointer) this.getResourcePointer(element))
				.getLocalViewInfo();
	}

	public void showLocalView(GS_RWElement element) {
		ArrayList<Quadruple<Connection, GSResourcePointer, GSExplanatoryNote, Integer>> info =
				((GSResourcePointer) this.getResourcePointer(element)).getLocalViewInfo();
			new LocalViewFrame(info).setVisible(true);
		}

	public GSResourcePointer getResourcePointer(GS_RWElement element) {
		return (GSResourcePointer) super.getResourcePointer(element);
	}

	public List<RWElement> getDirectElements(RWElement element) {
		return this.getDirectElements(this.getResourcePointer(element));
	}

	public List<GS_RWElement> getAllElements_for_RWMainPanel() {
		List<GS_RWElement> elements = new ArrayList<GS_RWElement>();
		List<ResourcePointer> pointers = this.getResourcePointers();
		RWElement element;
		for (int i = 0; i < pointers.size(); i++) {
			ResourcePointer pointer = pointers.get(i);
			if (pointer.isZombified()) continue;
			element = pointer.getGSResource();
			if (! (element instanceof GS_RWElement)) {
				GSLog.getInstance().warn("GS_RWRepository:" + 
			       i + "-th element is not GS_element: " + element);
			} else {
				elements.add((GS_RWElement)element);
			}
		}
		
		// BUGS!?
		List<GSConnection> connections = this.getConnections();
		for (int i = 0; i < connections.size(); i++) {
			element = connections.get(i);
			if (! (element instanceof GSConnection)) {
				GSLog.getInstance().warn("GS_RWRepository:" + 
			       i + "-th element is expected to be a GSConnection but it's not: " + element);
			} else {
				elements.add((GS_RWElement)element);
			}
		}
		
		
		return elements;
	}
	
	public List<RWElement> getAllRWElements() {
		List<RWElement> elements = new ArrayList<RWElement>();
		List<ResourcePointer> pointers = this.getResourcePointers();
		for (int i = 0; i < pointers.size(); i++) {
			elements.add(pointers.get(i).getGSResource());
		}
		return elements;
	}

	public void restore(Element rwElement) {
		Element desktopElement = (Element) rwElement.getElementsByTagName(
				"desktop").item(0);
		ReasoningWebDesktop.getInstance().restore(desktopElement);
		NodeList connectionList = rwElement.getElementsByTagName("connection");
		for (int i = 0; i < connectionList.getLength(); i++) {
			Element element = (Element) connectionList.item(i);
			GSConnection connection = GSConnection.restore(element);
			this.register(connection.getSourcePointer());
			this.register(connection.getTargetPointer());
			this.addConnection(connection);
		}
		this.resourceBaskets.clear();
		NodeList basketList = rwElement.getElementsByTagName(URIObject.RESOURCE_BASKET);
		for (int i = 0; i < basketList.getLength(); i++) {
			Element element = (Element) basketList.item(i);
			ResourceBasket basket = ResourceBasket.restore(element);
			basket.setToBeSaved(true);
			this.addResourceBasket(basket);
		}
		ResourceBasketsFrame.renew();

		//2009/04/22 North Grid
		connectionList = rwElement.getElementsByTagName("background");
		if( connectionList.getLength() > 0 ){
			Element background = (Element) connectionList.item(0);
			String temp = background.getAttribute("file");
			if( temp != null && temp.length() > 0 ){
				backgroundFilePath = temp;
			}
		}
	}

	public void addResourceBasket(ResourceBasket basket) {
		if (!this.resourceBaskets.contains(basket)) {
			this.resourceBaskets.add(basket);
		}
	}

	public void save(Document document, Element parent) {
		Element element = document.createElement("reasoning_web");
		ReasoningWebDesktop.getInstance().save(document, element);
		for (int i = 0; i < this.connections.size(); i++) {
			GSConnection connection = (GSConnection) this.connections.get(i);
			Element elem = connection.createXMLElement(document);
			element.appendChild(elem);
		}
		for (int i = 0; i < this.resourceBaskets.size(); i++) {
			ResourceBasket basket = (ResourceBasket)this.resourceBaskets.get(i);
			Element elem = basket.createXMLElement(document);
			NodeList list = element.getElementsByTagName(URIObject.RESOURCE_BASKET);
			boolean contain = false;
			for (int j = 0; j < list.getLength(); j++) {
				if (list.item(j).equals(elem)) {
					contain = true;
					break;
				}
			}
			if (!contain) {
				element.appendChild(elem);
			}
		}
		parent.appendChild(element);

		//2009/04/22 North Grid
		if( backgroundFilePath != null && backgroundFilePath.length() > 0 ){
			Element background = document.createElement("background");
			background.setAttribute("file", backgroundFilePath);
			element.appendChild(background);
		}
	}

	// 2007/11/1 kazuhiro kobayashi
	public void removeConnection(Connection connection) {
		if (connection != null) {
			//2007/11/19 kazuhiro kobayashi
			this.connections.remove(connection);
			connection.getSourcePointer().removeConnection(connection);
			connection.getTargetPointer().removeConnection(connection);
			if (!connection.getSourcePointer().hasConnection()) {
				this.pointers.remove(connection.getSourcePointer());
				WorkspaceWindow.setUpdated(true);
			}
			if (!connection.getTargetPointer().hasConnection()) {
				this.pointers.remove(connection.getTargetPointer());
				WorkspaceWindow.setUpdated(true);
			}
		}
	}

	public void removePointer(ResourcePointer pointer) {
		if (pointer != null) {
			this.pointers.remove(pointer);
		}
	}

	public String getBackgroundFilePath() {
		return backgroundFilePath;
	}

	public void setBackgroundFilePath(String backgroundFilePath) {
		this.backgroundFilePath = backgroundFilePath;
	}

	public List<GSResource> getResourceBaskets() {
		return this.resourceBaskets;
	}
	
	public boolean isInBasket(GSResource resource) {
		for (int i = 0; i < this.resourceBaskets.size(); i++) {
			ResourceBasket basket = (ResourceBasket)this.resourceBaskets.get(i);
			if (basket.contains(resource)) return true;
		}
		return false;
	}

	public void deleteResourceFromBaskets(GSResource resource) {
		for (int i = 0; i < this.resourceBaskets.size(); i++) {
			ResourceBasket basket = (ResourceBasket)this.resourceBaskets.get(i);
			basket.removeResource(resource);
			ResourceBasketsFrame.getInstance().getSelectionFrame(basket).setBasket(basket);
		}
	}

	public void clear() {
		ReasoningWebDesktop.getInstance().clear();
		this.initialize();
		this.resourceBaskets.clear();
	}

	public void removeLastConnection() {
		Connection element = this.getConnections().get(this.getConnections().size()-1);
		GS_RWRepository.getInstance().removeConnection((Connection)element);
	}
}
