package dassault.arbor.io;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import dassault.arbor.arbor.db.ArborSqlCreate;
import dassault.arbor.arbor.db.ArborSqlGetData;
import dassault.arbor.arbor.db.ArborSqlGetId;
import dassault.arbor.arbor.db.ArborSqlUpdateData;
import dassault.arbor.arbor.dialog.ArborChoixOptions;
import dassault.arbor.arbor.ressources.ArborInterface;
import dassault.arbor.arbor.ressources.ArborOperateur;
import dassault.arbor.cecilia.ResArbor;
import dassault.arbor.desktop.DesktopView;
import dassault.core.db.DatabaseIdentifier;
import dassault.core.db.Law;
import dassault.core.db.ValueParameter;
import dassault.core.ressources.ArborRessources;

public class FileCaftaImport extends AbstractTreeFileImport implements ArborRessources, ArborOperateur, ArborInterface {
  private static final int GATE_LIST_ALPHAB_DATA = 0;

  private static final int GATE_LIST_DEPTH_DATA = 1;

  private static final int GATE_DESC_DATA = 2;

  private static final int EVENT_PROB_DESC_DATA = 3;

  private static final int EVENT_WITH_TYPE_DATA = 4;

  private int m_currentLine;

  private Map m_Nodes = new HashMap();

  private Set m_RootGates = new HashSet();

  private String m_CurrentRoot = null;

  private Set m_haveOutputs = new HashSet();

  public FileCaftaImport(String projectName, int projectObjectID, int projectVersionID, String systemName,
      int systemObjectID, int systemVersionID) {
    super(projectName, projectObjectID, projectVersionID, systemName, systemObjectID, systemVersionID);
  }

  // _____________PUBLIC MEMBERS________________________________________________________________________

  public boolean readFiles(List filePathList) {
    return readFiles((String) filePathList.get(0), (String) filePathList.get(1), (String) filePathList.get(2),
        (String) filePathList.get(3), (String) filePathList.get(4));
  }

  protected boolean readFiles(String gateListAlphabeticalFilePath, String gateListDepthFirstFilePath,
      String gateDescriptionsFilePath, String basicEventProbDescFilePath, String basicEventWithTypeCodeFilePath) {
    boolean error = false;
    if (gateListDepthFirstFilePath == null && gateListAlphabeticalFilePath == null) {
      getErrorManager().addMessage(ResArbor.getString(ResArbor.KEY_1225));
      error = true;
    }
    if (basicEventProbDescFilePath == null && basicEventWithTypeCodeFilePath == null) {
      getErrorManager().addMessage(ResArbor.getString(ResArbor.KEY_1226));
      error = true;
    }
    if (error == true)
      return false;

    if (gateListDepthFirstFilePath != null) {
      if (readGateListDepthFirstFilePath(gateListDepthFirstFilePath) == false) {
        getErrorManager().addMessage(
        		ResArbor.msgFormat(ResArbor.KEY_1227, gateListDepthFirstFilePath));
        error = true;
      }
    }
    else {
      if (readGateListAlphbetical(gateListAlphabeticalFilePath) == false) {
        getErrorManager().addMessage(
        		ResArbor.msgFormat(ResArbor.KEY_1227, gateListAlphabeticalFilePath));
        error = true;
      }
    }
    if (gateDescriptionsFilePath != null)
      if (readGateDescriptionsFilePath(gateDescriptionsFilePath) == false) {
        getErrorManager().addMessage(
        		ResArbor.msgFormat(ResArbor.KEY_1227, gateDescriptionsFilePath));
        error = true;
      }

    if (basicEventWithTypeCodeFilePath != null) {
      if (readBasicEventWithTypeCodeFilePath(basicEventWithTypeCodeFilePath) == false) {
        getErrorManager().addMessage(
        		ResArbor.msgFormat(ResArbor.KEY_1227, basicEventWithTypeCodeFilePath));
        error = true;
      }
    }
    else {
      if (readBasicEventProbDescFilePath(basicEventProbDescFilePath) == false) {
        getErrorManager().addMessage(
        		ResArbor.msgFormat(ResArbor.KEY_1227, basicEventProbDescFilePath));
        error = true;
      }
    }
    if (error == true)
      return false;

    Iterator i = m_Nodes.keySet().iterator();
    while (i.hasNext()) {
      String node = (String) i.next();
      if (!m_haveOutputs.contains(node))
        m_RootGates.add(node);
    }
    if (m_RootGates.isEmpty()) {
      getErrorManager().addMessage(ResArbor.getString(ResArbor.KEY_1234));
      return false;
    }

    // Affichage des informations sur les portes/\u00e9v\u00e9nements pour le
    // deboggage
    /*
     * System.out.print("Root gates -> "); i = m_RootGates.iterator(); while(
     * i.hasNext() ) System.out.print(i.next()+" "); System.out.println();
     * System.out.println("Gates/Events"); i = m_Nodes.values().iterator();
     * while( i.hasNext() ) { Object node = i.next(); if (
     * node.getClass().getName().endsWith("Event") ) { Event event =
     * (Event)node; System.out.println("Event: "+event.m_Name+" "+
     * event.m_FailureModel.m_Type+" "+ event.m_FailureModel.m_Rate+" "+
     * event.m_FailureModel.m_Factor+" "+ event.m_Description); } else { Gate
     * gate = (Gate)node; System.out.print("gate: "+gate.m_Name+"
     * type="+gate.m_Type+" desc="+gate.m_Description+" inputs="); Iterator
     * inputs = gate.inputs.iterator(); while( inputs.hasNext() )
     * System.out.print(inputs.next()+" "); System.out.println(); } }
     */
    return true;
  }

  public boolean convert() {
    try {
      return convertToArbor();
    }
    catch (Exception e) {
      e.printStackTrace();
      getErrorManager().addMessage(ResArbor.getString(ResArbor.KEY_1224));
      return false;
    }
  }

  public boolean convertToArbor() {
    // Convertion des arbres Cafta en arbres Arbor
    Iterator i = m_RootGates.iterator();
    while (i.hasNext()) {
      Iterator nodes = m_Nodes.values().iterator();
      while (nodes.hasNext()) {
        ((Node) nodes.next()).m_bTreated = false;
      }
      String rootName = (String) i.next();
      m_CurrentRoot = rootName;
      Node root = (Node) m_Nodes.get(rootName);
      StringBuffer equation = new StringBuffer();
      StringBuffer definition = new StringBuffer();

      // Construction des equations et d\u00e9finition de l'arbre
      if (convertNodeToAralia(root, equation, definition) == false) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1235, m_CurrentRoot) );
        return false;
      }

      // Cr\u00e9ation de l'arbre Arbor
      if (createArborTree(root.m_Name, equation, definition) == false) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1236, m_CurrentRoot) );
      }
    }
    return true;
  }

  // _____________PROTECTED PRIVATE MEMBERS_____________________________________________________________

  protected boolean readGateListAlphbetical(String gateListAlphabeticalFilePath) {
    LineNumberReader in = openPrepareFile(gateListAlphabeticalFilePath, GATE_LIST_ALPHAB_DATA);
    if (in == null)
      return false;

    try {
      // Lecture des donn\u00e9es utiles
      String ln = null;
      while ((ln = in.readLine()) != null && ln != null && ln.length() != 0) {
        StringTokenizer tok = new StringTokenizer(ln, "\t");
        String name = tok.nextToken();
        Gate gate = (Gate) m_Nodes.get(name);
        if (gate == null)
          m_Nodes.put(name, gate = new Gate());
        gate.m_Name = name;
        gate.m_Type = tok.nextToken();
        while (tok.hasMoreTokens()) {
          String input = tok.nextToken();
          gate.inputs.add(input);
          m_haveOutputs.add(input);
        }
      }
    }
    catch (IOException e) {
      getErrorManager().addMessage(
    		  ResArbor.msgFormat(ResArbor.KEY_1230, gateListAlphabeticalFilePath));
      return false;
    }
    return true;
  }

  protected boolean readGateListDepthFirstFilePath(String gateListDepthFirstFilePath) {
    LineNumberReader in = openPrepareFile(gateListDepthFirstFilePath, GATE_LIST_DEPTH_DATA);
    if (in == null)
      return false;

    try {
      // Lecture des donn\u00e9es utiles
      String ln = null;
      while ((ln = in.readLine()) != null && ln != null && ln.length() != 0) {
        StringTokenizer tok = new StringTokenizer(ln, "\t");
        String name = tok.nextToken();
        Gate gate = (Gate) m_Nodes.get(name);
        if (gate == null)
          m_Nodes.put(name, gate = new Gate());
        gate.m_Name = name;
        gate.m_Type = tok.nextToken();
        while (tok.hasMoreTokens()) {
          String input = tok.nextToken();
          gate.inputs.add(input);
          m_haveOutputs.add(input);
        }
      }
    }
    catch (IOException e) {
      getErrorManager().addMessage(
    		  ResArbor.msgFormat(ResArbor.KEY_1230, gateListDepthFirstFilePath));
      return false;
    }
    return true;
  }

  protected boolean readGateDescriptionsFilePath(String gateDescriptionsFilePath) {
    LineNumberReader in = openPrepareFile(gateDescriptionsFilePath, GATE_DESC_DATA);
    if (in == null)
      return false;

    try {
      // Lecture des donn\u00e9es utiles
      String ln = null;
      while ((ln = in.readLine()) != null && ln != null && ln.length() != 0) {
        StringTokenizer tok = new StringTokenizer(ln, "\t", true);
        String name = tok.nextToken();
        Gate gate = (Gate) m_Nodes.get(name);
        if (gate == null)
          m_Nodes.put(name, gate = new Gate());
        gate.m_Name = name;
        if (tok.hasMoreTokens())
          tok.nextToken(); // skip tab
        while (tok.hasMoreTokens())
          gate.m_Description += tok.nextToken();
      }
    }
    catch (IOException e) {
      getErrorManager().addMessage(
    		  ResArbor.msgFormat(ResArbor.KEY_1230, gateDescriptionsFilePath) );
      return false;
    }
    return true;
  }

  protected boolean readBasicEventProbDescFilePath(String basicEventProbDescFilePath) {
    LineNumberReader in = openPrepareFile(basicEventProbDescFilePath, EVENT_PROB_DESC_DATA);
    if (in == null)
      return false;

    try {
      // Lecture des donn\u00e9es utiles
      String ln = null;
      while ((ln = in.readLine()) != null && ln != null && ln.length() != 0) {
        StringTokenizer tok = new StringTokenizer(ln, "\t", true);
        String name = tok.nextToken();
        Event event = (Event) m_Nodes.get(name);
        if (event == null)
          m_Nodes.put(name, event = new Event());
        event.m_Name = name;
        if (!tok.hasMoreTokens()) // aucune d'info
          continue;
        tok.nextToken(); // skip tab
        if (!tok.hasMoreTokens()) // aucune d'info
          continue;
        String data = tok.nextToken();
        if (!data.equals("\t"))
          if (tok.hasMoreTokens())
            tok.nextToken(); // skip Prob.
        while (tok.hasMoreTokens())
          event.m_Description += tok.nextToken();
      }
    }
    catch (IOException e) {
      getErrorManager().addMessage(
    		  ResArbor.msgFormat(ResArbor.KEY_1230, basicEventProbDescFilePath));
      return false;
    }
    return true;
  }

  protected boolean readBasicEventWithTypeCodeFilePath(String basicEventWithTypeCodeFilePath) {
    LineNumberReader in = openPrepareFile(basicEventWithTypeCodeFilePath, EVENT_WITH_TYPE_DATA);
    if (in == null)
      return false;

    try {
      // Lecture des donn\u00e9es utiles
      String ln = null;
      while ((ln = in.readLine()) != null && ln != null && ln.length() != 0) {
        StringTokenizer tok = new StringTokenizer(ln, "\t", true);
        String name = tok.nextToken();
        Event event = (Event) m_Nodes.get(name);
        if (event == null)
          m_Nodes.put(name, event = new Event());
        event.m_Name = name;
        if (!tok.hasMoreTokens())
          continue;
        tok.nextToken(); // skip tab
        if (!tok.hasMoreTokens())
          continue;
        String rate = tok.nextToken();
        if (!rate.equals("\t")) {
          event.m_FailureModel.m_Rate = new Float(rate).floatValue();
          if (!tok.hasMoreTokens())
            continue;
          tok.nextToken(); // skip tab
        }
        if (!tok.hasMoreTokens())
          continue;
        String Ur = tok.nextToken();
        if (!Ur.equals("\t")) {
          if (!tok.hasMoreTokens())
            continue;
          tok.nextToken(); // skip tab
        }
        if (!tok.hasMoreTokens())
          continue;
        String factor = tok.nextToken();
        if (!factor.equals("\t")) {
          event.m_FailureModel.m_Factor = new Float(factor).floatValue();
          if (!tok.hasMoreTokens())
            continue;
          tok.nextToken(); // skip tab
        }
        if (!tok.hasMoreTokens())
          continue;
        String Uf = tok.nextToken();
        if (!Uf.equals("\t")) {
          if (!tok.hasMoreTokens())
            continue;
          tok.nextToken(); // skip tab
        }
        if (!tok.hasMoreTokens())
          continue;
        String type = tok.nextToken();
        if (!type.equals("\t")) {
          event.m_FailureModel.m_Type = new Integer(type).intValue();
          if (!tok.hasMoreTokens())
            continue;
          tok.nextToken(); // skip tab
        }
        else {
          event.m_bLaw = false;
          getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1233, 
          	basicEventWithTypeCodeFilePath, event.m_Name) );
        }
        if (!tok.hasMoreTokens())
          continue;
        String prob = tok.nextToken();
        if (!prob.equals("\t")) {
          if (!tok.hasMoreTokens())
            continue;
          tok.nextToken(); // skip tab
        }
        while (tok.hasMoreTokens())
          event.m_Description += tok.nextToken();
      }
    }
    catch (IOException e) {
      getErrorManager().addMessage(
    		  ResArbor.msgFormat(ResArbor.KEY_1230, basicEventWithTypeCodeFilePath));
      return false;
    }
    return true;
  }

  protected LineNumberReader openPrepareFile(String filePath, int dataType) {
    LineNumberReader in = null;
    try {
      in = new LineNumberReader(new FileReader(filePath));
      if (readFileHeader(in, filePath, dataType) == false) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1228, filePath) );
        return null;
      }
    }
    catch (FileNotFoundException e) {
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1229, filePath) );
      return null;
    }
    return in;
  }

  protected boolean readFileHeader(LineNumberReader in, String filePath, int dataType) {
    try {
      String ln = in.readLine();
      if (ln == null) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1232, filePath));
        return false;
      }
      if (!ln.equals(getHeaderLine(dataType))) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1231, filePath));
        return false;
      }
      if (in.readLine() == null) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1232, filePath));
        return false;
      }
      if (in.readLine() == null) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1232, filePath));
        return false;
      }
      if (in.readLine() == null) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1232, filePath));
        return false;
      }
      if (in.readLine() == null) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1232, filePath));
        return false;
      }
    }
    catch (IOException e) {
      getErrorManager().addMessage(
    		  ResArbor.msgFormat(ResArbor.KEY_1230, filePath));
      return false;
    }
    return true;
  }

  protected String getHeaderLine(int dataType) {
    switch (dataType) {
    case GATE_LIST_ALPHAB_DATA:
      return "Fault Tree List Report (Alphabetical)";
    case GATE_LIST_DEPTH_DATA:
      return "Fault Tree List Report (Depth First)";
    case GATE_DESC_DATA:
      return "Gate Description Report";
    case EVENT_PROB_DESC_DATA:
      return "Basic Event Description Report";
    case EVENT_WITH_TYPE_DATA:
      return "Basic Event and Type Code Data Report";
    default:
      return null;
    }
  }

  protected boolean convertNodeToAralia(Node node, StringBuffer equation, StringBuffer definition) {
    if (node.m_bTreated == true)
      return true;
    if (node.getClass().getName().endsWith("Event")) {
      if (convertEventToAralia((Event) node, equation, definition) == false)
        return false;
    }
    else if (node.getClass().getName().endsWith("Gate")) {
      // Traitement de la porte
      if (convertGateToAralia((Gate) node, equation, definition) == false)
        return false;
      if (!m_RootGates.contains(node.m_Name) || node.m_Name.equals(m_CurrentRoot)) {
        // Traitement des entr\u00e9es de la porte
        Iterator i = ((Gate) node).inputs.iterator();
        while (i.hasNext()) {
          Node input = (Node) m_Nodes.get(i.next());
          convertNodeToAralia(input, equation, definition);
        }
      }
    }
    node.m_bTreated = true;
    return true;
  }

  protected boolean convertGateToAralia(Gate gate, StringBuffer equation, StringBuffer definition) {
    // Nom
    definition.append("<NAME>");
    definition.append(gate.m_Name);
    definition.append("\n");

    // Commentaire
    if (gate.m_Description != null && gate.m_Description.length() != 0) {
      definition.append("<COMMENT>");
      definition.append(gate.m_Description);
      definition.append("\n");
    }
    /*
     * // Suppression des portes EQU des entr\u00e9es de la porte trait\u00e9e
     * String inputName; List inputList = new ArrayList(); Iterator i =
     * gate.inputs.iterator(); while( i.hasNext() ) { inputName =
     * (String)i.next(); Object input = m_Nodes.get(inputName); // Cas des
     * portes de type EQU, on court-circuite la porte while(
     * input.getClass().getName().endsWith("Gate") &&
     * ((Gate)input).m_Type.equals("EQU") ) { getErrorManager().addMessage(
     * ImportRessources.EQU_GATE_DELETED, ((Gate)input).m_Name, m_CurrentRoot );
     * inputName = (String)((Gate)input).inputs.get(0); input =
     * m_Nodes.get(inputName); } inputList.add(inputName); }
     */
    String inputName = null;
    List inputList = gate.inputs;
    Iterator i = null;
    // FIN MODIF
    if (inputList.isEmpty())
      return true;

    i = inputList.iterator();
    inputName = (String) i.next();
    int vote = 2;

    StringBuffer line = new StringBuffer();
    line.append(AraliaSep_1);
    line.append(gate.m_Name);
    line.append(AraliaSep_2);
    line.append(" := ");

    char operator = ',';
    if (gate.m_Type.equals("AND")) {
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = inputList.size() >= 2 ? '&' : '|';
    }
    else if (gate.m_Type.equals("INH")) {
      getErrorManager().addMessage(
    		  ResArbor.msgFormat(ResArbor.KEY_1241, gate.m_Name, m_CurrentRoot) );
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = inputList.size() >= 2 ? '&' : '|';
    }
    else if (gate.m_Type.equals("NOT")) {
      line.append('-');
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '|';
    }
    else if (gate.m_Type.equals("NOR")) {
      line.append('-');
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '|';
    }
    else if (gate.m_Type.equals("NAND")) {
      line.append('-');
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '&';
    }
    else if (gate.m_Type.equals("OANB")) {
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1242, gate.m_Name, m_CurrentRoot));
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '|';
    }
    else if (gate.m_Type.equals("ONAB")) {
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1243, gate.m_Name, m_CurrentRoot));
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1246, inputName, inputName, "Not_" + inputName, m_CurrentRoot) );
      if (inputList.size() >= 2)
        line.append('(');
      line.append('-');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '|';
    }
    else if (gate.m_Type.equals("AANB")) {
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1244, gate.m_Name, m_CurrentRoot));
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '&';
    }
    else if (gate.m_Type.equals("ANAB")) {
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1245, gate.m_Name, m_CurrentRoot));
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1246, inputName, inputName, "Not_" + inputName, m_CurrentRoot) );
      if (inputList.size() >= 2)
        line.append('(');
      line.append('-');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '&';
    }
    else if (gate.m_Type.equals("EQU")) {
      // return true; // Ce type de porte n'existe pas dans Arbor.
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '|';
    }
    else if (gate.m_Type.equals("OR")) {
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = '|';
    }
    else if (gate.m_Type.equals("PAG")) {
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1240, gate.m_Name, m_CurrentRoot));
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = inputList.size() >= 2 ? '&' : '|';
    }
    else if (gate.m_Type.startsWith("COM")) {
      vote = new Integer(gate.m_Type.substring(3)).intValue();
      if (vote <= 1)
        return false;
      if (vote >= inputList.size()) {
        if (inputList.size() >= 2)
          line.append('(');
      }
      else {
        line.append("@(");
        line.append(vote);
        line.append(",[");
      }
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = vote >= inputList.size() ? '&' : ',';
    }
    else if (gate.m_Type.equals("XOR")) {
      if (inputList.size() >= 2)
        line.append('(');
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
      operator = inputList.size() >= 2 ? '#' : '|';
    }

    while (i.hasNext()) {
      line.append(" ");
      line.append(operator);
      line.append(" ");
      inputName = (String) i.next();
      if (gate.m_Type.equals("OANB") || gate.m_Type.equals("AANB")) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1246, 
        		inputName, inputName, "Not_" + inputName, m_CurrentRoot) );
        line.append('-');
      }
      line.append(AraliaSep_1);
      line.append(inputName);
      line.append(AraliaSep_2);
    }
    if (gate.m_Type.startsWith("COM") && vote < inputList.size())
      line.append(']');
    if (inputList.size() >= 2)
      line.append(')');

    line.append(";\n");
    equation.append(line);

    return true;
  }

  protected boolean convertEventToAralia(Event event, StringBuffer equation, StringBuffer definition) {
    // Nom
    definition.append("<NAME>");
    definition.append(event.m_Name);
    definition.append("\n");

    // Commentaire
    if (event.m_Description != null && event.m_Description.length() != 0) {
      definition.append("<COMMENT>");
      definition.append(event.m_Description);
      definition.append("\n");
    }

    // Loi
    Law law = new Law();
    if (event.m_bLaw == true) {
      if (convertModelToAralia(event.m_FailureModel, law) == false) {
        getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1238, 
        		event.m_Name, m_CurrentRoot, Integer.toString(event.m_FailureModel.m_Type)) );
      }
    }
    definition.append("<LAW>");
    definition.append(law.getGenericLaw() == null ? "" : law.toString());
    definition.append("\n");

    return true;
  }

  protected boolean convertModelToAralia(FailureModel model, Law law) {
    law.setBoundTime(false, "0.0", "0.0");

    switch (model.m_Type) {
    case 0: // Constant, fixed
    {
      law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_CSTE));
      law.getParameters().add(new ValueParameter(model.m_Factor)); // q
      break;
    }
    case 1: // CMT
    {
      if (model.m_Factor == 0.0) {
        law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_EXP));
        law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
      }
      else {
        law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_TEMPS));
        law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
        law.getParameters().add(new ValueParameter(model.m_Factor)); // T
        law.getParameters().add(new ValueParameter((float) 0.0)); // q = 0
      }
      break;
    }
    case 2: // Dormant
    {
      law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_DORMANT));
      law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
      law.getParameters().add(new ValueParameter((float) 0.0)); // MTTR = 0
      law.getParameters().add(new ValueParameter(model.m_Factor)); // T
      break;
    }
    case 3: // CMT
    {
      if (model.m_Factor == 0.0) {
        law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_EXP));
        law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
      }
      else {
        law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_TEMPS));
        law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
        law.getParameters().add(new ValueParameter(model.m_Factor)); // T
        law.getParameters().add(new ValueParameter((float) 0.0)); // q = 0
      }
      break;
    }
    case 4: // GLM aymptotique
    {
      law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_GLMA));
      law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
      law.getParameters().add(new ValueParameter((float) 1.0 / model.m_Factor)); // Mu
      break;
    }
    case 5: // Dormant
    {
      law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_DORMANT));
      law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
      law.getParameters().add(new ValueParameter((float) 0.0)); // MTTR = 0
      law.getParameters().add(new ValueParameter(model.m_Factor)); // T
      break;
    }
    case 6: // GLM
    {
      law.setGenericLaw(m_GenericLawSet.getLawBySymbolicName(ResArbor.LAW_GLM));
      law.getParameters().add(new ValueParameter((float) 0.0)); // Gamma
      law.getParameters().add(new ValueParameter(model.m_Rate)); // Lambda
      law.getParameters().add(new ValueParameter((float) 1.0 / model.m_Factor)); // Mu
      break;
    }
    default:
      return false;
    }
    return true;
  }

  protected boolean createArborTree(String treeName, StringBuffer equation, StringBuffer definition) {
    if (ArborSqlGetData.treeNameExist(m_SystemObjectID, m_SystemVersionID, treeName) == true) {
      getErrorManager().addMessage(ResArbor.msgFormat(ResArbor.KEY_1237, treeName));
      return false;
    }

    // Creation de l'arbre Arbor dans la base Arbor
    // Creation de la version associe a l'arbre a creer
    int objectID = createObject();
    int versionID = createObjectVersion(objectID);
    
    // Creation de l'arbre
    int treeFolderId = ArborSqlCreate.createTree(-1, m_SystemVersionID, treeName, "");
    int treeVersionFolderId = ArborSqlCreate.createTreeVersion(versionID, treeFolderId, "1.0", "");
    
    // Reconstruction de l'equation finale de l'arbre.
    if (equation.length() == 0) {
      equation.append(AraliaSep_1);
      equation.append(treeName);
      equation.append(AraliaSep_2);
      equation.append(" :=1;\n"); // Pas d'evenements.
    }

    // Reconstruction de la definition finale de l'arbre.
    StringBuffer definitionFinal = new StringBuffer();
    definitionFinal.append("<ARBORJAVA>\n");
    definitionFinal.append(definition);
    definitionFinal.append("\n");
    boolean result = ArborSqlUpdateData.saveTree(versionID, objectID, equation.toString(), definitionFinal.toString(), false);
    if (result == false)
      return false;
    
    // Ajout de l'arbre dans le gestionnaire des arbres
    ArborChoixOptions arborOptions = DesktopView._mainFrame.getArborChoixOptions();
    int groupAccess = arborOptions.getAccessForGroup();
    int otherAccess = arborOptions.getAccessForOther();
    _gestionnaire.addTreeInList(treeFolderId, treeVersionFolderId,
        objectID, versionID,
        m_ProjectName, m_SystemName, treeName, 1, 0, groupAccess, otherAccess);

    return true;
  }

  protected int createObject() {
    return ArborSqlGetId.getObjectId();
  }

  protected int createObjectVersion(int objectID) {
    ArborChoixOptions arborOptions = DesktopView._mainFrame.getArborChoixOptions();
    int objVerId = -1;
    if (DatabaseIdentifier.isOracle())
      objVerId = ArborSqlGetId.getObjectVersionId();
    ArborSqlCreate.createObjectVersion(objectID, objVerId,
        arborOptions.getGroupId(), arborOptions.getUserId(),
        arborOptions.getAccessForGroup(), arborOptions.getAccessForOther(), "1.0", "");
    if (!DatabaseIdentifier.isOracle())
      objVerId = ArborSqlGetId.getObjectVersionId();
    return objVerId;
  }

}

class Node {
  public String m_Name;

  public String m_Description = "";

  public boolean m_bTreated = false;
}

class Event extends Node {
  public boolean m_bLaw = true;

  public FailureModel m_FailureModel = new FailureModel();
}

class Gate extends Node {
  public String m_Type = "OR";

  public List inputs = new ArrayList();
}

class FailureModel {
  public int m_Type = 0;

  public float m_Rate = (float) 0.0;

  public float m_Factor = (float) 0.0;
}
