
package jp.riken.brain.ni.samuraigraph.application;

import java.awt.Component;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.swing.JFileChooser;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import jp.riken.brain.ni.samuraigraph.base.SGDrawingWindow;
import jp.riken.brain.ni.samuraigraph.base.SGExtensionFileFilter;
import jp.riken.brain.ni.samuraigraph.base.SGFileChooser;
import jp.riken.brain.ni.samuraigraph.base.SGIConstants;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;


/**
 * Create a property file.
 */
public class SGPropertyFileCreator
	implements SGIConstants, SGIPropertyFileConstants
{

	/**
	 * A file chooser to save property files.
	 */
	private JFileChooser mFileChooser;

	
	/**
	 * Constructs an object.
	 *
	 */
	public SGPropertyFileCreator()
	{
		this.init();
	}
	
	private void init()
	{
		JFileChooser chooser = new SGFileChooser();
		this.mFileChooser = chooser;

		// set the file extension filter
		SGExtensionFileFilter ff = new SGExtensionFileFilter();
		ff.setDescription( PROPERTY_FILE_DESCRIPTION );
		ff.addExtension( PROPERTY_FILE_EXTENSION );
		chooser.setFileFilter(ff);

		// set default directory name and file name of the property file
		String path = USER_HOME;
		String md = MY_DOCUMENTS;
		File home = new File( path );
		String[] fList = home.list();
		if( fList==null )
		{
			throw new Error();
		}
		for( int ii=0; ii<fList.length; ii++ )
		{
			if( fList[ii].endsWith(md) )
			{
				path += FILE_SEPARATOR + md;
				break;
			}
		}

		String fileName = path + FILE_SEPARATOR + DEFAULT_PROPERTY_FILE_NAME + "." + PROPERTY_FILE_EXTENSION;
		chooser.setSelectedFile( new File( fileName ) );
	}



	/**
	 * Create a property file.
	 */
	public int create( SGDrawingWindow wnd, File file )
	{
		// export to the XML file
		FileOutputStream os = null;
		try
		{
			os = new FileOutputStream( file );
			return this.create( wnd, os );
		}
		catch( Exception ex )
		{
			return -1;
		}
		finally
		{
			if( os!=null )
			{
				try
				{
					os.close();
				}
				catch( IOException ex )
				{
				}
			}
		}
	}


	/**
	 * Create a property file.
	 */
	public int create( SGDrawingWindow wnd, String pathName )
	{
		// export to the XML file
		FileOutputStream os = null;
		try
		{
			os = new FileOutputStream( pathName );
			return this.create( wnd, os );
		}
		catch( Exception ex )
		{
			return -1;
		}
		finally
		{
			if( os!=null )
			{
				try
				{
					os.close();
				}
				catch( IOException ex )
				{
				}
			}
		}
	}


	//
	private int create( SGDrawingWindow wnd, OutputStream os ) throws Exception
	{
		DOMImplementation domImpl = SGApplicationUtility.getDOMImplementation();
		if( domImpl==null )
		{
			return -1;
		}

		// create a DocumentType object
		DocumentType docType = domImpl.createDocumentType(
			ROOT_TAG_NAME, PROPERTY_FILE_PUBLIC_ID, PROPERTY_FILE_SYSTEM_ID );
		
		// create a Document object
		Document document = domImpl.createDocument( "", ROOT_TAG_NAME, docType );

		// create a DOM tree
		if( wnd.createDOMTree( document ) == false )
		{
			return -1;
		}
		
		// export to the XML file
		StreamResult result = new StreamResult(os);
		DOMSource source = new DOMSource( document );
		TransformerFactory transFactory = TransformerFactory.newInstance();
		Transformer transformer = transFactory.newTransformer();

		// set the output properties
		transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
		transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
		transformer.setOutputProperty( OutputKeys.DOCTYPE_SYSTEM, PROPERTY_FILE_SYSTEM_ID );
		transformer.setOutputProperty( OutputKeys.DOCTYPE_PUBLIC, PROPERTY_FILE_PUBLIC_ID );

		transformer.transform( source, result );
		
		return OK_OPTION;
	}


	/**
	 * Create a property file.
	 */
	public int create( SGDrawingWindow wnd )
	{
		// show a file chooser and get selected file
		File file = this.getPropertyFileFromFileChooser( wnd );
		if( file==null )
		{
			return CANCEL_OPTION;
		}

		return this.create( wnd, file );		
	}



	/**
	 * 
	 * @param wnd
	 * @return
	 */
	private File getPropertyFileFromFileChooser( Component parent )
	{
		JFileChooser chooser = this.mFileChooser;

		// show save dialog
		final int ret = chooser.showSaveDialog(parent);

		File file = null;
		if( ret == JFileChooser.APPROVE_OPTION )
		{
			file = chooser.getSelectedFile();
		}

		return file;
	}


	/**
	 * 
	 * @return
	 */
	public File getSelectedFile()
	{
		if( this.mFileChooser==null )
		{
			return null;
		}
		else
		{
			return this.mFileChooser.getSelectedFile();
		}
	}


	/**
	 * Set the file name to the file chooser.
	 * @param dir - directory name
	 * @param name - file name
	 * @return a File object
	 */
	public File setFile( String dir, String name )
	{
		if( name==null )
		{
			name = "";
		}

		// set current directory
		this.mFileChooser.setCurrentDirectory( new File(dir) );

		// create the full path name
		String path = dir + FILE_SEPARATOR + name;
		File f = new File(path);

		// set selected file
		this.mFileChooser.setSelectedFile(f);

		return f;
	}


}

