import javax.xml.parsers.*;
import javax.xml.transform.*;
import java.io.File;

import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.codehaus.groovy.control.CompilationFailedException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import groovy.swing.SwingBuilder
import javax.swing.JFileChooser 
import javax.swing.JOptionPane;

// This is that Script.groovy file for the task "Card titles, contents, and tags"
// VERSION NUMBER: 1.0.3

/*************************************************************************
* 
* This Groovy program (also called an export filter) transforms the
* XML-formatted information in an infocard file to some other textual format
* by executing an XSLT transformation on the original infocard file.
* 
* You can create export filters that format selected data from an infocard
* file into whatever textual format you find useful. To do so:
* 
* 1. Write an XSLT file that transforms an infocard file into the desired
*    format.
* 2. Place that XSLT file in the scripts/supportfiles folder.
* 3. Copy this Groovy file and rename it to reflect the function of the XSLT
*    transformation. The filename (minus its extension) will become the
*    menu item that the user will use to select the desired export type.
* 4. In this file, set the value of the variable xsltFilename to the name of
*    your XSLT file.
* 5. Place this Groovy file in the scripts/exports folder.
* 
* After you have done this, when you execute the Export menu item, the
* file-chooser dialog will display your export filter, as given by the name
* of the associated Groovy file (the file you are currently reading).
* 
***************************************************************************/



class Script {

	static void main(Object activeWindowFilePathObject)  {
	
		 // look for "return" to break out of this loop
		while (true)  {
	
			// use a FileChooser to determine where to put output of XSLT transformation
			// result is in outputFile, which is either a File or null
			def swing = new SwingBuilder()
			File outputFile = null
			def fileChooser = swing.fileChooser()
			fileChooser.dialogTitle = "Save Export Output"
			if (fileChooser.showSaveDialog()==JFileChooser.APPROVE_OPTION) {
				outputFile = fileChooser.getSelectedFile()
				println outputFile.toString()
			}
			
			// if null, user has clicked Cancel, so exit this program without
			// doing any exporting
			if (outputFile == null)
				  return
				
			if (outputFile.exists()) {
				
				// discover whether user wants to override existing file
				def myFilename = outputFile.getName()				
				String dialogText = "Are you sure you want to overwrite file $myFilename?"
				def dialogValue = JOptionPane.showConfirmDialog(null, dialogText,
						"Overwrite File?", JOptionPane.YES_NO_OPTION)
					
				// restart at top of loop if the user does not want to overwrite chosen file
				if (dialogValue == JOptionPane.NO_OPTION) {
					continue
				}
			}
			
			// if program arrives here, it is safe to transform the input file given by
			// activeWindowFilePath and save it to a file specified by outputFile
			
			System.setProperty("javax.xml.transform.TransformerFactory",
			"net.sf.saxon.TransformerFactoryImpl");
			
			/**************************************************************************
			 * 
			 * To change the transformation that this export function performs, change
			 * the value of xsltFilename to the name of the XSLT file that you have
			 * deposited in the supportfiles folder  
			 * 
			 **************************************************************************/
			String xsltFilename =  "Card titles, contents, and tags v1_03.xsl";
	
			String activeWindowFilePath = (String) activeWindowFilePathObject;	
			File stylesheet = new File(System.getProperty("user.dir") + File.separator + 
					"scripts"      + File.separator + 
					"supportfiles" + File.separator + 
					xsltFilename);
	
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setNamespaceAware(true);
			
		    try {			    	
			  	  File infocardFile = new File(activeWindowFilePath);

			  	  DocumentBuilder builder = factory.newDocumentBuilder();
			  	  Document document = builder.parse(infocardFile);

			  	  //	Use a Transformer for output
			  	  TransformerFactory tFactory =
			  		  TransformerFactory.newInstance();
			  	  StreamSource stylesource = new StreamSource(stylesheet);
			  	  Transformer transformer =
			  		  tFactory.newTransformer(stylesource);

			  	  DOMSource source = new DOMSource(document);
			  	  
			  	  StreamResult result = new StreamResult(outputFile);
			  	  
			  	  //  transformation occurs here; output is sent to result
			  	  transformer.transform(source, result);
			  	  
			    } catch (TransformerConfigurationException tcException) {
			  	  // Error generated by the parser
			  	  System.out.println ("\n** Transformer Factory error");
			  	  System.out.println("   " + tcException.getMessage() );

			  	  // Use the contained exception, if any
			  	  Throwable x = tcException;
			  	  if (tcException.getException() != null)
			  		  x = tcException.getException();
			  	  x.printStackTrace();

			    } catch (TransformerException tException) {
			  	  // Error generated by the parser
			  	  System.out.println ("\n** Transformation error");
			  	  System.out.println("   " + tException.getMessage() );

			  	  // Use the contained exception, if any
			  	  Throwable x = tException;
			  	  if (tException.getException() != null)
			  		  x = tException.getException();
			  	  x.printStackTrace();

			    } catch (SAXException sxException) {
			  	  // Error generated by this application
			  	  // (or a parser-initialization error)
			  	  Exception  x = sxException;
			  	  if (sxException.getException() != null)
			  		  x = sxException.getException();
			  	  x.printStackTrace();

			    } catch (ParserConfigurationException pcException) {
			  	  // Parser with specified options can't be built
			  	  pcException.printStackTrace();

			    } catch (IOException ioException) {
			  	  // I/O error
			  	  ioException.printStackTrace();
			    }
			
			    // transformation has occurred, file was written; program should exit
			    return
		
		}

	}
}