package hiro.yoshioka.sql.notes.ddl;

import hiro.yoshioka.sdh.ResultSetDataHolder;
import hiro.yoshioka.util.StringUtil;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Par implements Serializable {
	private static final long serialVersionUID = 1100579708591302868L;
	List<PardefElement> elementList;
	int def;
	Document parent;

	public Par(Document form, Node atts) {
		this.parent = form;
		if (atts != null) {
			NamedNodeMap names = atts.getAttributes();
			this.def = Form.getAttrValueInt(names, "def");
			NodeList listPar = ((Node) atts).getChildNodes();
			for (int j = 0; j < listPar.getLength(); j++) {
				Node childPar = listPar.item(j);
				if ("run".equals(childPar.getNodeName())) {
					parseRun(this, childPar);
				} else if ("urllink".equals(childPar.getNodeName())) {
					parseUrlLink(this, childPar);
				} else if ("region".equals(childPar.getNodeName())) {
					parseRegion(this, childPar);
				} else if ("picture".equals(childPar.getNodeName())) {
					addElement(new Picture(childPar));
				} else {
					System.err.println("       ??   par#child="
							+ childPar.getNodeName());
				}
			}
		}
	}

	public Document getParent() {
		return parent;
	}

	private void parseRegion(Par par, Node region) {
		Region l = new Region(region);
		addElement(l);
	}

	private void parseUrlLink(Par par, Node link) {
		UrlLink l = new UrlLink(link);
		addElement(l);
	}

	private void parseRun(Par par, Node run) {
		NodeList list = run.getChildNodes();

		Font font = null;
		Field field = null;
		for (int i = 0; i < list.getLength(); i++) {
			Node child = list.item(i);
			if ("font".equals(child.getNodeName())) {
				font = new Font(child);
				par.addElement(font);
			} else if ("field".equals(child.getNodeName())) {
				field = new Field(child);
				par.addElement(field);
			} else if ("sharedfieldref".equals(child.getNodeName())) {
				NamedNodeMap names = child.getAttributes();
				field = this.parent.getSharedField(Form.getAttrValueString(
						names, "name"));
				if (field != null) {
					par.addElement(field);
				}
			} else if (Node.TEXT_NODE == child.getNodeType()) {
				if (child.getTextContent().replaceAll("[\r\n]", "").trim()
						.length() > 0) {
					if (font != null) {
						font.setCharactor(child.getTextContent());
					}
				}
			} else {
				System.out.println("     ??parseRun#child="
						+ child.getNodeName());
			}
		}
	}

	public int getDef() {
		return def;
	}

	public void addElement(PardefElement element) {
		if (elementList == null) {
			elementList = new ArrayList<PardefElement>();
		}
		elementList.add(element);
	}

	@Override
	public String toString() {
		if (elementList == null) {
			return super.toString();
		}
		StringBuilder buf = new StringBuilder();
		for (PardefElement element : elementList) {
			buf.append(String.format("    %s%n", element.toString()));
		}
		return buf.toString();
	}

	public Object itemToHtmlString() {
		if (elementList == null) {
			return StringUtil.EMPTY_STRING;
		}
		StringBuilder buf = new StringBuilder();
		buf.append(String.format("<p class='par_%d'>%n", getDef()));

		boolean generatedFontTag = false;
		for (PardefElement element : elementList) {
			if (element instanceof Font) {
				if (generatedFontTag) {
					buf.append(String.format("</span>"));
				}
				generatedFontTag = true;
			}
			buf.append(String.format("%s", element.itemToHtmlString()));
		}

		buf.append(String.format("</span></p>%n"));
		return buf.toString();
	}

	public String toHtmlString(ResultSetDataHolder rdh, int row, File imgDir) {
		if (elementList == null) {
			return StringUtil.EMPTY_STRING;
		}
		StringBuilder buf = new StringBuilder();
		buf.append(String.format("<p class='par_%d'>%n", getDef()));

		for (PardefElement element : elementList) {
			buf.append(String.format("%s%n",
					element.toHtmlString(rdh, row, imgDir)));
		}
		buf.append(String.format("</p>%n"));
		return buf.toString();
	}

}
