/* $Id: CreateXMLElementVisitor.java 1108 2016-05-17 01:48:46Z shayashi $ */
package smart_gs.logical.visitor;

import java.util.List;
import java.util.Stack;

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

import smart_gs.logical.GSResource;
import smart_gs.logical.ResourceBasket;
import smart_gs.logical.URIObject;
import smart_gs.logical.UsersNote;
import smart_gs.logical.UsersNoteDirectory;
import smart_gs.logical.Region;
import smart_gs.logical.Spread;
import smart_gs.logical.SpreadDirectory;
import smart_gs.logical.IDAT;
import smart_gs.logical.StandardTextDocument;
import smart_gs.logical.TextSegment;
import smart_gs.logical.ZombieGSResourceForRestoring;
import smart_gs.reasoning_web.logical.GSExplanatoryNote;
import smart_gs.util.GSStandardPath;

public class CreateXMLElementVisitor implements Visitor {

	private Document document;
	private Stack<Element> elements;

	public CreateXMLElementVisitor(Document document) {
		this.document = document;
		this.elements = new Stack<Element>();
	}

	public void visit(Spread spread) {
		if (spread.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = document.createElement("spread");
		element.setAttribute(GSResource.NAME, spread.getName());
		element.setAttribute(GSResource.URI, spread.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, spread.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, spread.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, spread.getVersion());

		element.setAttribute("firstIDATName", spread.getFirstIDATNameToSave());
		element.setAttribute("secondIDATName", spread.getSecondIDATNameToSave());
		element.setAttribute("thirdIDATName", spread.getThirdIDATNameToSave());
		element.setAttribute("ocrIDATName", spread.getOcrIDATNameToSave());

		String filepath = spread.getFile().getPath();
		
//		TODO 20110910 shayashi
		element.setAttribute("filename", GSStandardPath.standardizeFileName(filepath));

		List<Region> regions = spread.getRegions();

		for (int i = 0; i < regions.size(); i++) {
			Region reg = regions.get(i);
			if (! (reg.isTemporary()|| reg.isZombie())) {
				regions.get(i).accept(this);
				Element elm = this.elements.pop();
				if (elm != null) element.appendChild(elm);
			}
		}

		spread.getFirstIDAT().accept(this);
		element.appendChild(this.elements.pop());
		spread.getSecondIDAT().accept(this);
		element.appendChild(this.elements.pop());
		spread.getThirdIDAT().accept(this);
		element.appendChild(this.elements.pop());
		spread.getOcrIDAT().accept(this);
		element.appendChild(this.elements.pop());

		elements.push(element);
	}

	public void visit(Region region) {
		if (region.isZombie()){
			elements.push(null);
			return;
		}
		Element element = document.createElement("region");
		element.setAttribute(GSResource.NAME, region.getName());
		element.setAttribute(GSResource.URI, region.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, region.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, region.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, region.getVersion());
		// kazuhiro kobayashi
		element.setAttribute("protection", region.isProtected());
		element.appendChild(region.getView().createXMLElement(document));
		this.elements.push(element);
	}

	public void visit(IDAT doc) {
		if (doc.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = this.document.createElement("spreadDocument");
		element.setAttribute("type", doc.getType() + "");
		element.setAttribute(GSResource.URI, doc.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, doc.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, doc.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, doc.getVersion());

		element.setAttribute("source", doc.getSource());

		List<TextSegment> segments = doc.getSegments();

		for (int i = 0; i < segments.size(); i++) {
			segments.get(i).accept(this);
			Element elm = this.elements.pop();
			if (elm != null) element.appendChild(elm);
		}
		this.elements.push(element);
	}

	public void visit(TextSegment segment) {
		if (segment.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = this.document.createElement("segment");
		element.setAttribute(GSResource.ID, segment.getId() + "");
		element.setAttribute("tagname", segment.getTagName());
		element.setAttribute(GSResource.URI, segment.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, segment.getOriginalURI());
		element.setAttribute(GSResource.VERSION, segment.getVersion());

		this.elements.push(element);
	}

	public void visit(SpreadDirectory directory) {
		if (directory.isZombie()){
			elements.push(null);
			return;
		}
		Element element = this.document.createElement("directory");
		element.setAttribute(GSResource.NAME, directory.getName());
		element.setAttribute(GSResource.URI, directory.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, directory.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, directory.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, directory.getVersion());

		//2007/12/1 kazuhiro kobayashi
		String dirpath = directory.getFile().getPath();
//		shayashi 2011.05.26
		element.setAttribute("filename", GSStandardPath.standardizeDirName(dirpath));

		List<GSResource> resources = directory.getResources();
		for (int i = 0; i < resources.size(); i++) {
			resources.get(i).accept(this);
			Element elm = this.elements.pop();
			if (elm != null) element.appendChild(elm);
		}
		this.elements.push(element);
	}

	// 20070923 shimizu wrote;
	public void visit(UsersNote usersNote) {
		if (usersNote.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = this.document.createElement("usersNote");
		element.setAttribute("source", usersNote.getSource());
		element.setAttribute(GSResource.NAME, usersNote.getName());
		element.setAttribute(GSResource.ID, usersNote.getId() + "");
	//20071212 shimizu wrote;
		element.setAttribute(GSResource.URI, usersNote.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, usersNote.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, usersNote.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, usersNote.getVersion());

		List<TextSegment> segments = usersNote.getSegments();
		for (int i = 0; i < segments.size(); i++) {
			segments.get(i).accept(this);
			Element elm = this.elements.pop();
			if (elm != null) element.appendChild(elm);
		}
		this.elements.push(element);
	}
	
	// 2011.04.19 shayashi
	@Override
	public void visit(UsersNoteDirectory usersNoteDirectory) {
		if (usersNoteDirectory.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = this.document.createElement("usersNoteDirectory");
		element.setAttribute(GSResource.NAME, usersNoteDirectory.getName());
		element.setAttribute(GSResource.URI, usersNoteDirectory.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, usersNoteDirectory.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, usersNoteDirectory.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, usersNoteDirectory.getVersion());

		List<GSResource> resources = usersNoteDirectory.getResources();
		for (int i = 0; i < resources.size(); i++) {
			resources.get(i).accept(this);
			Element elm = this.elements.pop();
			if (elm != null) element.appendChild(elm);
		}
		this.elements.push(element);
	}

	public void visit(StandardTextDocument textDocument) {
		if (textDocument.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = this.document.createElement("standardDocument");
		element.setAttribute(GSResource.URI, textDocument.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, textDocument.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, textDocument.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, textDocument.getVersion());
		element.setAttribute(GSResource.NAME, textDocument.getName());
		element.setAttribute("source", textDocument.getSource());
		List<TextSegment> segments = textDocument.getSegments();
		for (int i = 0; i < segments.size(); i++) {
			segments.get(i).accept(this);
			Element elm = this.elements.pop();
			if (elm != null) element.appendChild(elm);

		}
		this.elements.push(element);
	}

	public void visit(GSExplanatoryNote note) {
		if (note.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = this.document.createElement("explanatory");
		element.setAttribute("source", note.getSource());
		element.setAttribute(GSResource.NAME, note.getName());
		element.setAttribute(GSResource.ID, note.getId() + "");
		element.setAttribute(GSResource.URI, note.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, note.getOriginalURI());
		element.setAttribute(GSResource.OLD_VERSION_URI, note.getOldVersionURI());
		element.setAttribute(GSResource.VERSION, note.getVersion());

		List<TextSegment> segments = note.getSegments();
		for (int i = 0; i < segments.size(); i++) {
			segments.get(i).accept(this);
			Element elm = this.elements.pop();
			if (elm != null) element.appendChild(elm);
		}
		this.elements.push(element);

	}

	public Element getLastElement() {
		return this.elements.pop();
	}
	

	@Override
	public void visit(ZombieGSResourceForRestoring zombie) {
		if (zombie.isZombie()) {
			elements.push(null);
			return;
		}
		Element element = this.document.createElement(URIObject.ZOMBIE);
		element.setAttribute("deadURI", zombie.getDeadURI());
		element.setAttribute(GSResource.URI, zombie.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, zombie.getOriginalURI());
		element.setAttribute(GSResource.VERSION, zombie.getVersion());

		this.elements.push(element);		
	}

	public void visit(ResourceBasket resourceBasket) {
		if (resourceBasket.isZombie()) {
			elements.push(null);
			return;
		}
		if (!resourceBasket.toBeSaved()) {
			return;
		}
		Element element = this.document.createElement(URIObject.RESOURCE_BASKET);
		element.setAttribute(GSResource.URI, resourceBasket.getURI());
		element.setAttribute(GSResource.ORIGINAL_URI, resourceBasket.getOriginalURI());
		element.setAttribute(GSResource.VERSION, resourceBasket.getVersion());
		element.setAttribute(GSResource.NAME, resourceBasket.getName());
		for (int i = 0; i < resourceBasket.getResources().size(); i++) {
			Element elem = this.document.createElement(ResourceBasket.RESOURCE_URI);
			elem.setTextContent(resourceBasket.getResources().get(i).getURI());
			element.appendChild(elem);
		}
		this.elements.push(element);		
	}
}