package com.interpress_project.modernshare.client.controller.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Properties;

import org.exolab.castor.util.LocalConfiguration;

import com.interpress_project.modernshare.AppKeys;
import com.interpress_project.modernshare.client.controller.model.castor.Configure;
import com.interpress_project.modernshare.client.controller.model.castor.Target;
import com.interpress_project.modernshare.ipcommon.SystemBase;

public class XmlDAOManager {
	private SystemBase sb = SystemBase.getInstance();
	private final PropertyManager propmgr = PropertyManager.getInstance();
	private Configure configure = new Configure();
	private boolean bXMLLoaded = false, bNeedXMLSave = false;

	/**
	 * XmlDAOManager
	 */
	public XmlDAOManager() {
		// Set up properties for castor.		
		Properties props = LocalConfiguration.getInstance().getProperties();
		props.setProperty("org.exolab.castor.parser", "org.apache.xerces.parsers.SAXParser");
		props.setProperty("org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerializer");
		props.setProperty("org.exolab.castor.regexp", "org.exolab.castor.util.JakartaRegExpEvaluator");
		props.setProperty("org.exolab.castor.indent", "true");
		props.setProperty("org.exolab.castor.parser.validation", "false");
		props.setProperty("org.exolab.castor.parser.namespaces", "false");
		props.setProperty("org.exolab.castor.marshalling.validation", "true");
		props.setProperty("org.exolab.castor.debug", "false");
	}

	/**
	 * load
	 */
	public void load() {
		sb.getLogger().debug("Enter load() in XMLDAOManager.");

		FileInputStream fis;
		InputStreamReader isr = null;
		try {
			fis = new FileInputStream(propmgr.getXMLFileName());
			isr = new InputStreamReader(fis, AppKeys.ENCODING);
			configure = Configure.unmarshal(isr);
			bXMLLoaded = true;
		}
		catch (Exception e) {
			sb.getLogger().warn("Fail to load XML file, create new one.");
		}
		finally {
			try {
				isr.close();
			}
			catch (IOException ex) {
			}
		}
	}

	/**
	 * save
	 */
	public void save() {
		sb.getLogger().debug("Enter save() in XMLDAOManager.");

		try {
			FileOutputStream fos = new FileOutputStream(sb.getUserHomeDirectory() + "/" + AppKeys.XmlFilename);
			OutputStreamWriter osw = new OutputStreamWriter(fos, AppKeys.ENCODING);
			configure.marshal(osw);
			osw.close();
			//			needXMLSave(true); // Need remote store.			
		}
		catch (Exception ex) {
			sb.getLogger().warn("Fail to save XML file, create new one.", ex);
		}
	}

	/**
	 * getLocalRoots
	 * @return
	 */
	public LocalRoot[] getLocalRoots() {
		ArrayList<LocalRoot> list = new ArrayList<LocalRoot>();
		Target[] targets = configure.getTarget();
		for (int i = 0; i < targets.length; i++) {
			String folder = targets[i].getFolder();
			String tagname = targets[i].getTagname();
			RootStatus status = null;
			if (new File(folder).exists()) {
				status = RootStatus.valueOf(targets[i].getStatus());
			}
			else {
				status = RootStatus.disable;
			}
			boolean direction = targets[i].getPc2host();
			LocalRoot localRoot = new LocalRoot(folder, tagname, status, direction);
			list.add(localRoot);
		}
		return list.toArray(new LocalRoot[list.size()]);
	}

	/**
	 * setLocalRoots
	 * @param localRoots
	 */
	public void setLocalRoots(LocalRoot[] localRoots) {
		configure.removeAllTarget();

		for (int i = 0; i < localRoots.length; i++) {
			Target target = new Target();
			target.setFolder(localRoots[i].getAbsolutePath());
			if (new File(localRoots[i].getAbsolutePath()).exists()) {
				target.setStatus(localRoots[i].getStatus().name());
			}
			else {
				target.setStatus(RootStatus.disable.name());
			}
			target.setTagname(localRoots[i].getName());
			target.setPc2host(localRoots[i].getPc2host());

			configure.addTarget(target);
		}
	}

	/**
	 * hasXMLLoaded
	 * @return
	 */
	public boolean hasXMLLoaded() {
		return bXMLLoaded;
	}

	/**
	 * hasXMLModified
	 * @return
	 */
	public boolean needXMLSave() {
		return bNeedXMLSave;
	}

	/**
	 * setXMLModified
	 * @param b
	 */
	public void needXMLSave(boolean b) {
		bNeedXMLSave = b;
	}
}
