/**
 * プロジェクト名 laxIde
 * クラス名 LetsAjaxLayoutFileManager.java
 * 作成日: 2007/05/22
 * 
 */
package jp.co.cybec.laxide.file;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jp.co.cybec.laxide.file.template.LayoutTemplate;
import jp.co.cybec.laxide.model.base.AbstractModel;
import jp.co.cybec.laxide.model.base.LetsAjax2ColumnHeaderLayoutModel;
import jp.co.cybec.laxide.model.base.LetsAjax2ColumnLayoutModel;
import jp.co.cybec.laxide.model.base.LetsAjaxBodyModel;
import jp.co.cybec.laxide.model.base.LetsAjaxButtonModel;
import jp.co.cybec.laxide.model.base.LetsAjaxChartModel;
import jp.co.cybec.laxide.model.base.LetsAjaxCheckBoxModel;
import jp.co.cybec.laxide.model.base.LetsAjaxComboBoxModel;
import jp.co.cybec.laxide.model.base.LetsAjaxImageModel;
import jp.co.cybec.laxide.model.base.LetsAjaxLabelModel;
import jp.co.cybec.laxide.model.base.LetsAjaxLayoutConstant;
import jp.co.cybec.laxide.model.base.LetsAjaxLinkButtonModel;
import jp.co.cybec.laxide.model.base.LetsAjaxPlainLayoutModel;
import jp.co.cybec.laxide.model.base.LetsAjaxRadioButtonModel;
import jp.co.cybec.laxide.model.base.LetsAjaxTextAreaModel;
import jp.co.cybec.laxide.model.base.LetsAjaxTextFieldModel;
import jp.co.cybec.laxide.model.base.LetsAjaxTextModel;
import jp.co.cybec.laxide.model.extension.LetsAjaxDataTableModel;
import jp.co.cybec.laxide.model.extension.YuiBasicAnimateModel;
import jp.co.cybec.laxide.model.extension.YuiCalendarModel;
import jp.co.cybec.laxide.model.js.LetsAjaxJSControlModel;
import jp.co.cybec.laxide.model.js.YuiColorAnimateJSModel;
import lax.LetsAjaxActivator;

import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.graphics.RGB;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

/**
 * Laxファイルの読み込みと出力を行なうクラス ファイル名：LetsAjaxLayoutFileManager.java
 * 
 * @author nakamura 作成時刻：14:45:49
 * 
 */
public class LetsAjaxLayoutFileManager {

	/**
	 * レイアウトXMLファイルの生成.
	 * 
	 * @param parentModel
	 * @param path
	 */
	public void createLayoutFile(LetsAjaxBodyModel parentModel,
			final String path) {
		try {
			FileWriter file = new FileWriter(path, false);
			file.write(this.getLayoutBody(parentModel));
			file.flush();
			file.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * レイアウトXMLファイルのBODY部分を生成
	 * 
	 * @param parentModel
	 * @return
	 */
	private String getLayoutBody(LetsAjaxBodyModel parentModel) {
		// List<String> layoutHeaderList = this.getHeaderLayoutFileTag();
		List<String> layoutBodyList = new ArrayList<String>();

		layoutBodyList.add(parentModel.getLayoutXML());
		List list = parentModel.getChildren();
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			AbstractModel model = (AbstractModel) iter.next();
			layoutBodyList.add(model.getLayoutXML());
		}
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		// map.put("headList", layoutHeaderList);
		map.put("bodyList", layoutBodyList);

		LayoutTemplate template = new LayoutTemplate();
		return template.generate(map);
	}

	/**
	 * レイアウトファイルの読み込み.
	 * 
	 * @param file
	 * @param parent
	 */
	public void loadLayoutFile(final String file, LetsAjaxBodyModel parent) {
		Document document = this.createDocument(file);
		if (document != null) {
			Element root = document.getRootElement();
			setBodyModelFromXml(root, parent);
		}

	}

	/**
	 * LAXファイルをパースする。
	 * 
	 * @param fileName
	 * @return
	 */
	private Document createDocument(String fileName) {
		SAXBuilder builder = new SAXBuilder();
		try {
			Document document = builder.build(new File(fileName));
			return document;
		} catch (JDOMException e) {
			Plugin plugin = LetsAjaxActivator.getInstance();
			ILog log = plugin.getLog();
			log.log(new Status(IStatus.ERROR, LetsAjaxActivator.PLUGIN_ID, 0,
					"LAXファイルの解析に失敗しました", e));
			// e.printStackTrace();
		} catch (IOException e) {
			Plugin plugin = LetsAjaxActivator.getInstance();
			ILog log = plugin.getLog();
			log.log(new Status(IStatus.INFO, LetsAjaxActivator.PLUGIN_ID, 0,
					"LAXファイルがありません", e));
			// e.printStackTrace();
		} catch (Exception e) {
			Plugin plugin = LetsAjaxActivator.getInstance();
			ILog log = plugin.getLog();
			log.log(new Status(IStatus.ERROR, LetsAjaxActivator.PLUGIN_ID, 0,
					"LAXファイル内に異常があるかもしれません。", e));
			// e.printStackTrace();
		}
		return null;
	}

	/**
	 * BodyModelに値をセットする。
	 * 
	 * @param root
	 * @param parent
	 */
	private void setBodyModelFromXml(Element root, LetsAjaxBodyModel parent) {

		Element bodyEement = root
				.getChild(LetsAjaxLayoutConstant.LETSAJAX_BODY);
		String bgColor = bodyEement
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_BGCOLOR);
		String script = bodyEement
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_FORM_SCRIPT_ONLOAD);
		String title = bodyEement
				.getAttributeValue(LetsAjaxLayoutConstant.LETSAJAX_ATTRIBUTE_TITLE);
		// parent.setBgColor(bgColor);
		int red = 0;
		int green = 0;
		int blue = 0;

		String redColor = bgColor.substring(1, 3);
		if ((bgColor.substring(1, 3) != null && !redColor.equals(""))
				&& bgColor.length() >= 3) {
			red = Integer.parseInt(redColor, 16);
		}
		String greenColor = bgColor.substring(3, 5);
		if ((greenColor != null && !greenColor.equals(""))
				&& bgColor.length() >= 5) {
			green = Integer.parseInt(greenColor, 16);
		}
		String blueColor = bgColor.substring(5);
		if ((blueColor != null && !blueColor.equals(""))
				&& bgColor.length() == 7) {
			blue = Integer.parseInt(blueColor, 16);
		}
		parent.setBgColor(new RGB(red, green, blue));

		parent.setOnLoad(script);
		parent.setTitle(title);
		if (bodyEement != null) {
			this.setChildElementFromXml(bodyEement.getChildren(), parent);
		}

	}

	/**
	 * 子モデルに値をセットする。
	 * 
	 * @param childList
	 * @param parent
	 */
	private void setChildElementFromXml(List childList, LetsAjaxBodyModel parent) {
		for (Iterator iter = childList.iterator(); iter.hasNext();) {
			Element childElement = (Element) iter.next();
			AbstractModel model = this.createAbstractModel(childElement);
			parent.addChild(model);
		}
	}

	/**
	 * .laxファイルの部品の要素からモデルのインスタンスを生成する
	 * 
	 * @param element
	 *            子要素
	 * @return モデルのインスタンス
	 */
	private AbstractModel createAbstractModel(Element element) {
		AbstractModel model = null;
		if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_BUTTON)) {
			model = new LetsAjaxButtonModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_LABEL)) {
			model = new LetsAjaxLabelModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_TEXT)) {
			model = new LetsAjaxTextModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_TEXTFIELD)) {
			model = new LetsAjaxTextFieldModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_TEXTAREA)) {
			model = new LetsAjaxTextAreaModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_DATATABLE)) {
			model = new LetsAjaxDataTableModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_CHECKBOX)) {
			model = new LetsAjaxCheckBoxModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_RADIOBUTTON)) {
			model = new LetsAjaxRadioButtonModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_LINKBUTTON)) {
			model = new LetsAjaxLinkButtonModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_COMBO_BOX)) {
			model = new LetsAjaxComboBoxModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_IMAGE)) {
			model = new LetsAjaxImageModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_JS_SAMPLE_FUNCTION)) {
			model = new LetsAjaxJSControlModel();

		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_YUI_CALENDAR)) {
			model = new YuiCalendarModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_JS_CHART)) {
			model = new LetsAjaxChartModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_YUI_ANIMATE)) {
			model = new YuiBasicAnimateModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_JS_YUI_COLOR_ANIMATE)) {
			model = new YuiColorAnimateJSModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_2COLOMUN_LAYOUT)) {
			model = new LetsAjax2ColumnLayoutModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_PLAIN_LAYOUT)) {
			model = new LetsAjaxPlainLayoutModel();
		} else if (element.getName().equals(
				LetsAjaxLayoutConstant.LETSAJAX_BODY_2COLOMUN_HEADER_LAYOUT)) {
			model = new LetsAjax2ColumnHeaderLayoutModel();
		}

		model.setAttribute(element);
		return model;
	}

}
