// Copyright 2001 Joshua Levy

//package gmht ;

import java.util.* ;
import java.io.* ;
import org.apache.velocity.app.* ;
import org.apache.velocity.runtime.Runtime ;
import org.apache.velocity.* ;

/**
 * This class is still pretty messy.
 *
 * Here are the most commonly used methods, to create a
 * Form:
 * <PRE>
 *   Form f = new Form() ;
 *   Form f = new Form("Text goes here Dice(\"3d18\") $replace") ;
 *   Form f = new Form("Text goes here %replace:+% %replace:-%") ;
 *   Form f = new Form("Text: %profskills:<% %allskills:>%") ;
 *   p.add("Add more text to the Form") ;
 * </PRE>
 * These methods use Forms:
 * <PRE>
 *   String txt ;
 *   txt = p.trans() ;
 *   txt = p.trans("Text here $replace.") ;
 * </PRE>
 *
 */
public class Form 
      implements Serializable, Creator {
  static String sepFile = "\\" ;
  String str ;
  String pre ;
  StringTree ST ;
  String dir1, dir2 ;
  VelocityContext context ;
  Template template ;

  static {
       Velocity.init() ;
  }

  /**
   *
   */
  void setDir(String d1, String d2) {
      dir1 = d1 ;
      dir2 = d2 ; 
  }
   
  /**
   *
   */
  Form(String s) {
      template = null ;
      str = null ; 
      context = new VelocityContext() ; 
      try {
          if (s.endsWith(".vm")) 
              template = Runtime.getTemplate(s) ;
          else
              str = s ; 
      } catch (Exception ex) {
          System.out.println("Runtime.getTemplate failed") ;
          ex.printStackTrace() ;
          //throw ... XXX
      }
      if (false) 
          System.out.println("s="+s+" temp="+template+" str="+str) ;
  }

  Form() { this("") ; }

  /**
   *
   */
  //String trans() { return trans(null,str) ; }
  //String trans(StringTree st) { return trans(st,str) ; }
  //String trans(String s) { return trans(null,s) ; }

  // if only one %, ignore
  String trans(VelocityContext ctx) {
      StringWriter sw = new StringWriter() ;
      try {
          if (template!=null)
              template.merge(ctx,sw) ;
          else
              Velocity.evaluate(ctx, sw, "mystring", str) ;
      } catch (Exception ex) {
          System.out.println("Velocity.evaluate failed") ;
          ex.printStackTrace() ;
          //throw ... XXX
      }
      return sw.toString() ;
  }

  /**
   * This function writes the result of using the Form, but
   * writes it's result to a file.  It generally does whatever
   * trans does, but with one more argument, which is the file
   * name.  Here are some examples:
   * <PRE>
   *     void transToFile("new.htm") { 
   *     void transToFile(st, "new.txt") { 
   *     void transToFile(str, "new.htm") { 
   *     void transToFile(stree, str, "new.txt") {
   * </PRE>
   * here is a slightly more complex example:
   * <PRE>
   *    void use(int number) {
   *        int nn ;
   *        for(nn=0 ; nn<number ; nn++) {
   *            Form.transToFile("a:\\samp + nn + ".htm") ;
   *        }
   *    }
   * </PRE>
   */
  void transToFile(String filename) { 
      transToFile(null,filename) ; 
  }

  void transToFile(VelocityContext ctx, String filename) {
    FileWriter outStream ;
    try {
        outStream = new FileWriter(filename) ;
        PrintWriter ps = new PrintWriter(outStream) ;
        ps.println( trans(ctx) ) ;
        ps.close() ;
    } catch (IOException e) {
        System.out.println("StringTree.printXML failed for "+filename) ;
        System.out.print(e.toString()) ;
    }   
  }

  /**
   * The base and extension go together to make a file name 
   * like this:   baseN.extension
   * Where N is a number.
   *
   * @param count Number of forms to make.
   * @param base  The base file name.
   * @param extension What type of files to make (.txt, .html, etc.)
   *
  void forms(int count, String base, String extension) {
      int ii ;
      for(ii=0 ; ii<count ; ii++) {
          String where ;
          StringTree ntvv1 ;
          StringTree ntvv2 ;
          String r1 = "" ;
          String r2 = "" ;
          if (dir2!=null) {
              ntvv2 = StringTree.findAll(dir2) ;
              if (ntvv2!=null) {
                  r2 = ntvv2.getValue() ;
              }
              ntvv1 = StringTree.findAll(dir1) ;
              if (ntvv1!=null) {
                  r1 = ntvv1.getValue() ;
              }
              where = r1 + sepFile + r2 + sepFile + base + ii + "." + extension ;
          } else if (dir1!= null) {
              ntvv1 = StringTree.findAll(dir1) ;
              if (ntvv1!=null) {
                  r1 = ntvv1.getValue() ;
              }
              where = r1 + sepFile + base + ii + "." + extension ;
          } else {
              where = base + ii + "." + extension ;
          }
          System.out.print(where + "\n") ;
          System.out.print(trans(str)) ;
      }
  }
   */
   
  /*
   * The Creator interface
   */
  public String getName() { return "Form" ; }
  public String create() { return trans(context) ; }
  public String create(String arg) { return trans(context) ; }


  boolean equals(Form second) {
      return str.equals(second.str) ;
  }

  boolean equals(String second) {
      return str.equals(second) ;
  }

  public static void main(String[] args) {
      Form f1 = new Form("One two three") ;
      Form f2 = new Form("FormExample.vm") ;

      String s1 = f1.create() ;
      String s2 = f2.create() ;

      System.out.println("f1 trans to "+s1) ;
      System.out.println("f2 trans to "+s2) ;
  }
}
