//----------------------------------------------------------------------------
//
// Module:      FesiForm.java      
//
// Description: Public access routines and sample main program
//
// FESI Copyright (c) Jean-Marc Lugrin, 2000
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//----------------------------------------------------------------------------

package FesiForm;

import com.ibm.xml.parser.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import java.io.*;

import FESI.jslib.*;

public class FesiForm {
    
    // The EcmaScript interpreter for macros
    private JSGlobalObject global = null;
    private static String[] extensions = new String[] {"FESI.Extensions.BasicIOs",
                                                "FESI.Extensions.FileIO",
                                                "FESI.Extensions.JavaAccess",
                                                "FESI.Extensions.Database"
                                                };
    // Should be an identified input source (from SAX)
    private InputSource inputSource;
    private boolean trace = false;
                                           
    /**
     * Build a user interface handler based on an input source, make an internal interpreter
     */
    public  FesiForm(InputSource is) throws JSException {
       // Build the interpreter with common extensions
       inputSource = is;
       global = JSUtil.makeEvaluator(extensions);
    }
    
    /**
     * Build a user interface handler based on an input source and an interpreter
     */
    public FesiForm(InputSource is, JSGlobalObject go) throws JSException {
       // Use user interpreter
       inputSource = is;
       global = go;
    }
    
    public void setTrace(boolean t) {
        trace = t;
    }
    
    public boolean getTrace() {
        return trace;
    }
    
    /**
     * Process a FesiForm source, returning the GuiContext
     */
    public GuiContext process() throws JSException {
        org.xml.sax.Parser parser;
            
        // Detailed package name required to avoid name conflict
        try {
            parser = ParserFactory.makeParser(); // Use -Dorg.xml.sax.parser !
            // parser = ParserFactory.makeParser("com.ibm.xml.parser.SAXDriver");
            //com.microstar.xml.SAXDriver - does not work
        } catch (ClassNotFoundException ex) {
            throw new JSException("SAX Parser not found", ex);
        } catch (IllegalAccessException ex) {
            throw new JSException("SAX Parser cannot be loaded", ex);
        } catch (InstantiationException ex) {
            throw new JSException("SAX Parser cannot be instanciated", ex);
        }
        parser.setErrorHandler(new DefaultErrorHandler());
         
        GuiContext guiContext = new GuiContext(global, parser);
        try {
            global.setMember("__guiContext",guiContext);
            global.eval("function getById(_id) {return __guiContext.getById(_id);}");
        } catch (JSException ex) {
             System.err.println("Cannot initialize FESI: " + ex.getMessage());
             ex.printStackTrace();
             System.exit(1);
        }

        DocumentHandler guiDocumentHandler = new GuiDocumentHandler(guiContext, trace);
        parser.setDocumentHandler(guiDocumentHandler);
        try {
            parser.parse(inputSource);
        } catch (IOException ex) {
            throw new JSException("IO error processing xml", ex);
        } catch (SAXException ex) {
            throw new JSException("Parsing error processing xml", ex);
        }
    
        return guiContext;
        
    }
     
     
    /**
     * Main program mostly for testing
     */
    public static void main(String args[]) {
        boolean trace = false;
        FesiForm fesiForm;
        GuiContext gc;
        
        try {
                
            String filename = "form.xml";         // Defaults for test
            if (args.length>1) {
                if (args[0].equals("-t")) trace = true;
                filename=args[1];
            } else if (args.length>0) filename=args[0];
            
            FileReader fr = new FileReader(filename);
            InputSource is = new InputSource(fr);
            is.setPublicId(filename);
             
            fesiForm = new FesiForm(is);
            fesiForm.setTrace(trace);
            gc = fesiForm.process();
            
        } catch (Exception e) {
             e.printStackTrace();
             System.exit(1);
        }
    }
     
}
 
 