//==================================================================================================
// P r o g r a m                                                                               Java
// B u i l d J i r k
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library 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 Library General Public License for more details (http://www.gnu.org).

/*DESCRIPTION*/
/* This program generates the Jirk++ hierarchy representing a set of Java classes. The whole
   Java hierarchy is not generated. You only have to specify the Java class(es) you want to use
   in C++ and the program only generates the part of the hierarchy that is needed. If the Jirk++
   representation of a class already exists, nothing is done. Only the missing classes are added
   to the Jirk++ hierarchy. */

// Package //---------------------------------------------------------------------------------------
package bpp.program;

// Importation //-----------------------------------------------------------------------------------
import bpp.*;
import bpp.java.reflection.*;
import bpp.standard.*;
import java.io.*;
import java.util.*;

@SuppressWarnings("unchecked")

// B u i l d J i r k  Class //----------------------------------------------------------------------
/*CLASS BuildJirk */ /* This class provides a method to execute the program in console mode. */
public class BuildJirk {
 //---------------------------------------------------------------------------------------------Main
 /*METHOD BuildJirk */ /* Launches the program in a console display. */
 public static void main(String agParameterS[])
 { run(agParameterS,new bpp.display.JavaConsole()); }
 //----------------------------------------------------------------------------------------------Run
 /*METHOD BuildJirk */
 /* Start method of the program. It deals with the commands the user gives through a command
    line and executes the appropriate functions. */
 public static int run(String agParameterS[],OutputTextStream agOut) {
  InputTextStream  lcFin;
  OutputTextStream lcFout;
  String           lcParameter;
  String           lcString;

  TreeSet lcClassS       = new TreeSet();
  int     lcCounter      = 0;
  boolean lcDisplayed    = true;
  boolean lcError        = true;
  int     lcLength       = agParameterS.length;
  String  lcObjectPath   = "";
  boolean lcShortCommand = false;
  String  lcSourcePath   = ".";
  String  lcSeparator    = "/";
  Vector  lcStandardS    = new Vector();

  try {
   while (lcCounter<lcLength) {
    lcParameter=agParameterS[lcCounter];
    lcError=true;
    ++lcCounter;

    if (lcParameter.equals("+help")) {
     lcError=false;
     agOut.writeLine();
     agOut.writeLine("[>] -=-=- H E L P -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
     agOut.writeLine("     This program generates the Jirk++ hierarchy of a set of Java classes.");
     agOut.writeLine("     The whole Java hierarchy is not generated. You only have to specify the");
     agOut.writeLine("     Java class(es) you want to use in C++ and the program only generates the");
     agOut.writeLine("     part of the hierarchy that is needed. If the Jirk++ representation of a");
     agOut.writeLine("     class already exists, nothing is done. Only the  missing classes are");
     agOut.writeLine("     added to the Jirk++ hierarchy.");
     agOut.writeLine();
     agOut.writeLine("     * Syntax: [options] [commands]");
     agOut.writeLine();
     agOut.writeLine("     * Options:");
     agOut.writeLine("       -file <f>      = indicates a file <f> containing a list of Java");
     agOut.writeLine("                        classes to add into the Jirk++ hierarchy.");
     agOut.writeLine("       -hide          = deactivates the display of information.");
     agOut.writeLine("       -objects <f>   = defines the folder where the binary objects");
     agOut.writeLine("                        will be stored at the compilation time.");
     agOut.writeLine("       -path <f>      = defines the folder where the Jirk++ hierarchy is");
     agOut.writeLine("                        created. Without this option, the hierarchy is");
     agOut.writeLine("                        stored in the current path.");
     agOut.writeLine("       -separator <s> = indicates the symbol <s> to use in the makefile");
     agOut.writeLine("                        to separate names in a path. The default is '/'.");
     agOut.writeLine("       -shortcommand  = generates short commands in the makefile.");
     agOut.writeLine("       -standard <f>  = indicates a file <f> containing a list of Java");
     agOut.writeLine("                        packages to consider as standard in Java.");
     agOut.writeLine();
     agOut.writeLine("     * Commands:");
     agOut.writeLine("       +help              = shows this help.");
     agOut.writeLine("       +info              = shows information about the program.");
     agOut.writeLine("       +license           = shows the license of the program.");
     agOut.writeLine("       +add <c1> <c2> ... = adds the Java classes <c1>, <c2>... into the");
     agOut.writeLine("                            Jirk++ hierarchy. If the '-file' option is used,");
     agOut.writeLine("                            the classes contained in the file are also added.");
     agOut.writeLine("       +makefile <f>      = generates the makefile <f> that compiles the");
     agOut.writeLine("                            Jirk++ hierarchy.");
     agOut.writeLine("    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
    }

    else if (lcParameter.equals("+info")) {
     lcError=false;
     agOut.writeLine();
     agOut.writeLine(JavaInformation.information("B u i l d   J i r k"));
    }

    else if (lcParameter.equals("+license")) {
     lcError=false;
     agOut.writeLine();
     agOut.writeLine(JavaInformation.license());
    }

    else if (lcParameter.equals("-file") && lcCounter<lcLength) {
     lcError=false;
     lcFin=new InputTextFile(agParameterS[lcCounter]);

     while (!lcFin.isEnded()) {
      lcString=lcFin.readString();
      if (!lcString.equals("")) lcClassS.add(new JirkClass(lcString));
     }

     ++lcCounter;
    }

    else if (lcParameter.equals("-hide")) {
     lcError=false;
     lcDisplayed=false;
    }

    else if (lcParameter.equals("-objects") && lcCounter<lcLength) {
     lcError=false;
     lcObjectPath=agParameterS[lcCounter];
     ++lcCounter;
    }

    else if (lcParameter.equals("-path") && lcCounter<lcLength) {
     lcError=false;
     lcSourcePath=agParameterS[lcCounter];
     ++lcCounter;
    }

    else if (lcParameter.equals("-separator") && lcCounter<lcLength) {
     lcError=false;
     lcSeparator=agParameterS[lcCounter];
     ++lcCounter;
    }

    else if (lcParameter.equals("-shortcommand")) {
     lcError=false;
     lcShortCommand=true;
    }

    else if (lcParameter.equals("-standard") && lcCounter<lcLength) {
     lcError=false;
     lcFin=new InputTextFile(agParameterS[lcCounter]);

     while (!lcFin.isEnded()) {
      lcString=lcFin.readString();
      if (!lcString.equals("")) lcStandardS.add(lcString);
     }

     ++lcCounter;
    }

    else if (lcParameter.equals("+add")) {
     lcError=false;

     while (lcCounter<lcLength) {
      lcClassS.add(new JirkClass(agParameterS[lcCounter]));
      ++lcCounter;
     }

     if (lcDisplayed) agOut.writeLine();
     JirkClass.generateHierarchy(lcSourcePath,lcClassS,agOut,lcDisplayed);
    }

    else if (lcParameter.equals("+makefile") && lcCounter<lcLength) {
     lcError=false;

     if (lcDisplayed) {
      agOut.writeLine();
      agOut.writeLine("[>] Generating Makefile...");
     }

     lcFout=new OutputTextFile(agParameterS[lcCounter]);
     Makefile.generate(lcFout,lcSourcePath,lcObjectPath,lcStandardS,lcSeparator,lcShortCommand);
     lcCounter++;
     ++lcCounter;
    }

    if (lcError) throw new Exception("BuildJirk - Use the '+help' parameter to get some help.");
   }

   if (lcError) throw new Exception("BuildJirk - Use the '+help' parameter to get some help.");
  }

  catch (Exception agException) {
   agOut.writeLine();
   agOut.writeLine("[!] "+agException.getMessage());
   return (1);
  }

  return (0);
 }
}

// End //-------------------------------------------------------------------------------------------