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.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

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

public class Document implements Serializable {
	private static final long serialVersionUID = -355123861119587236L;
	protected Map<Integer, Pardef> pardefMap = new LinkedHashMap<Integer, Pardef>();
	protected List<Par> parList = new ArrayList<Par>();
	Database parent;

	public Document(Database parent, Node atts) {
		this.parent = parent;
	}

	public Document(Node atts) {
		parseFormBody(atts);
	}

	public String toCssString() {
		StringBuilder buf = new StringBuilder();
		for (Integer i : pardefMap.keySet()) {
			Pardef def = pardefMap.get(i);
			buf.append(String.format(".par_%d{ %s }%n", i,
					def.toCssString(false)));
		}
		return buf.toString();
	}

	public String itemToHtmlString() {
		StringBuilder buf = new StringBuilder();
		System.out.println("parlist=" + parList);
		for (Par par : parList) {
			buf.append(par.itemToHtmlString());
		}
		return buf.toString();
	}

	public String toHtmlString(ResultSetDataHolder rdh, int row, File imgDir) {
		StringBuilder buf = new StringBuilder();
		for (Par par : parList) {
			buf.append(par.toHtmlString(rdh, row, imgDir));
		}
		return buf.toString();
	}

	public static Boolean getAttrValueBoolean(NamedNodeMap names, String key) {
		Node n = names.getNamedItem(key);
		if (n == null) {
			return null;
		}
		try {
			return Boolean.valueOf(n.getNodeValue());
		} catch (DOMException e) {
		}
		return null;
	}

	public static int getAttrValueInt(NamedNodeMap names, String key) {
		Node n = names.getNamedItem(key);
		if (n == null) {
			return 0;
		}
		return StringUtil.parseIntNoneException(n.getNodeValue(), 0);
	}

	public static void putAttrValueString(NamedNodeMap names, String key,
			Properties putProperties) {
		String val = Document.getAttrValueString(names, key);
		if (val != null) {
			putProperties.setProperty(key, val);
		}
	}

	public static String getAttrValueString(NamedNodeMap names, String key) {
		Node n = names.getNamedItem(key);
		if (n == null) {
			return null;
		}
		return n.getNodeValue();
	}

	public void putParDef(Pardef pardef) {
		pardefMap.put(pardef.getId(), pardef);
	}

	public void addPar(Par par) {
		parList.add(par);
	}

	public void parseBody(Node formNode) {
		NodeList list = formNode.getChildNodes();
		for (int i = 0; i < list.getLength(); i++) {
			Node child = list.item(i);

			if ("body".equals(child.getNodeName())) {
				System.out.println(" in Bodyyyyyyyyyyyyyyyyyy");
				parseFormBody(child);
			} else if ("item".equals(child.getNodeName())) {
				if (child.getAttributes().getLength() > 0) {
					Node attrName = child.getAttributes().getNamedItem("name");
					if (attrName != null) {
						if ("name".equals(attrName.getNodeName())) {
							// TODO:
							// フォームを作成し、文書を作成できるユーザーを指定する場合は、それらの名前が
							// [$FormUsers]
							// フィールドに格納されます。
							// attrName.getNodeValue()
						}
					}
				}

			} else {
				System.out.println("   ??parseForm#child="
						+ child.getNodeName());
			}
		}

	}

	private void parseFormBody(Node body) {
		NodeList list0 = body.getChildNodes();
		NodeList list = null;

		for (int i = 0; i < list0.getLength(); i++) {
			Node child = list0.item(i);
			if ("richtext".equals(child.getNodeName())) {
				list = child.getChildNodes();
				break;
			}
		}
		if (list == null) {
			return;
		}
		for (int i = 0; i < list.getLength(); i++) {
			Node child = list.item(i);
			// System.out.println("parseForm#child=" + child.getClass() +
			// "//"
			// + child.getLocalName() + "/" + child.getNodeName());

			if ("pardef".equals(child.getNodeName())) {
				Pardef pardef = new Pardef(child);
				putParDef(pardef);

			} else if ("table".equals(child.getNodeName())) {
				addPar(new Table(this, child));
			} else if ("par".equals(child.getNodeName())) {
				Par par = new Par(this, child);
				addPar(par);

			} else if (Node.TEXT_NODE == child.getNodeType()) {
				if (child.getTextContent().replaceAll("[\r\n]", "").trim()
						.length() > 0) {
					System.out.println("     ??parseFormBody#textNode["
							+ child.getTextContent() + "]");
				}
			} else {
				System.out.println("     ??parseFormBody#child="
						+ child.getNodeName());
			}
		}
	}

	public Field getSharedField(String attrValueString) {
		if (this.parent == null) {
			return null;
		}
		return parent.getSharedField(attrValueString);
	}

}
