/** 
 * Project    : KANT (LMT)
 * Source Name: Definition.java
 * Copyright  : Copyright (c) LTI, Carnegie Mellon University
 * Description: Class for usage definition
 * @version     1.0 (created by jko - 10/01/01)
 **/

package lmt;

import java.sql.*;
import java.util.*;

public class Definition {
  String definition_id;
  String concept_id;
  String usage_definition;
  String cte_usage;
  String audience;
  String active;
	
  Vector relatedTerms;
  Vector examples;
  SQLConnection con;
	
  /** constructor 
   **/
  public Definition(SQLConnection con, String con_id) {
    this.con = con;
    definition_id = "";
    concept_id = con_id;
    usage_definition = "";
    cte_usage = "";
    audience = "";
    active = "";
    examples = new Vector();
    relatedTerms = new Vector();
  }
	
  // setters and getters
  public String getDefinitionID() {
    return definition_id;
  }	
  public void setDefinitionID(String definition_id) {
    if ( definition_id == null )
      definition_id = "";
    this.definition_id = definition_id;
  }	
  public String getConceptID() {
    return concept_id;
  }	
  public void setConceptID(String concept_id) {
    if ( concept_id == null )
      concept_id = "";
    this.concept_id = concept_id;
  }		
  public String getUsageDefinition() {
    return usage_definition;
  }	
  public void setUsageDefinition(String usage_definition) {
    if ( usage_definition == null )
      usage_definition = "";
    this.usage_definition = usage_definition;
  }	
  public String getCteUsage() {
    return cte_usage;
  }	
  public void setCteUsage(String cte_usage) {
    if ( cte_usage == null )
      cte_usage = "";
    this.cte_usage = cte_usage;
  }	
  public String getAudience() {
    return audience;
  }	
  public void setAudience(String audience) {
    if ( audience == null )
      audience = "";
    this.audience = audience;
  }	
  public void setActive (String active) {
    this.active = active;
  }	

  /** get examples of this definition
   * @return Vector containing all examples of this definition
   **/
  public Vector getExamples() {
    if ( examples == null )
      examples = Example.fetch(con, definition_id);
    return examples;
  }	

  /** set examples of this definition
   * @parame Vector containing all examples of this definition
   **/	
  public void setExamples(Vector examples) {
    this.examples = examples;		
  }	

  /** get examples of this definition
   * @return Vector containing all examples of this definition
   **/
  public Vector getRelatedTerms() {
    if ( relatedTerms == null )
      relatedTerms = RelatedTerm.fetch(con, definition_id);
    return relatedTerms;
  }	

  /** set examples of this definition
   * @parame Vector containing all examples of this definition
   **/	
  public void setRelatedTerms(Vector relatedTerms) {
    this.relatedTerms = relatedTerms;		
  }		
		
  /** Get all definitions which are related with the concept
   * @param concept_id a string representing concept_id
   * @return Vector all definitions fetched from the database.
   **/			
  public static Vector fetchDefinitions(SQLConnection con, String concept_id) {
    Vector defVector = new Vector();
		
    String sql = "SELECT * FROM LMT_DEFINITIONS WHERE ";
    sql += " CONCEPT_ID = '" + concept_id + "'";
    sql += " ORDER BY DEFINITION_ID";

    Debug.debug("-- fetchDefinitions: " + sql);		

    try {
      SQLConnection.Result r = con.query(sql);
      while (r!=null &&r.hasData()){
	Definition definition = new Definition(con, concept_id);
					
	String definition_id = r.rs.getString(1);
	definition.setDefinitionID(definition_id);				 
	//definition.setConceptID(r.rs.getString(2));
	definition.setUsageDefinition(r.rs.getString(3));
	definition.setCteUsage(r.rs.getString(4));
	definition.setAudience(r.rs.getString(5));
	//definition.setRelatedTerm(r.rs.getString(6));
	definition.setActive(r.rs.getString(6));
					
	// fetch examples & related term
	definition.setExamples(Example.fetch(con, definition_id));
	definition.setRelatedTerms(RelatedTerm.fetch(con, definition_id));
					
	defVector.addElement(definition);	
      }
      if (r!=null) r.close();
    } catch (SQLException E) {
      Debug.debug("SQLException(in fetchDefinitions): " + E.getMessage());
    }	
		
    //Debug.debug("-- size of definition: " + defVector.size());	
    return defVector;
  }
	
  /** insert the new data into the table.
   * @return integer representing the result of operation
   **/		
  public int insert() {

    if ( isCteSelected() && cte_usage.equals("T")) {
      return Constants.DUPLICATION;
    }

    // get New Term ID				
    definition_id = con.getNewID("DEFINITION_ID");				
    active  = "T";
		
    String sql = "INSERT INTO LMT_DEFINITIONS VALUES (";
    sql += "'" + definition_id + "',";
    sql += "'" + concept_id + "',";
    sql += "'" + Util.replaceSingleQuote(usage_definition) + "',";
    sql += "'" + cte_usage + "',";
    sql += "'" + audience + "',";	
    sql += "'" + active + "')";

    Debug.debug("-- Definition insertion : " + sql);		
		
    return con.insert(sql);
  }

  /** delete this data from the table.
   * @return integer representing the result of operation
   **/			
  public int delete() {
    // check where this exists
    if (!isExistent())
      return Constants.DONOTEXIST;

    Debug.debug("-- Definition delete : ");		
		
    // delete definition with stored procedure
    // this will delete the definition, its examples, and it related terms.
    boolean ret = con.callProcedure("DeleteUsage", definition_id);
		
    // delete the examples and related terms from the memory
    if (ret) {
      if (relatedTerms != null)
	relatedTerms.removeAllElements();
      if (examples != null)
	examples.removeAllElements();
      return Constants.SUCCESS;
    } else
      return Constants.FAIL;		
		
  }

  /** update data in the table.
   * @return integer representing the result of operation
   **/	
  public static int update(SQLConnection con, Vector defVector) {
    if ( defVector == null || defVector.size() == 0)
      return Constants.SUCCESS;
		
    // make query
    Vector queryVector = new Vector();
    Definition.makeQuery(queryVector, defVector);
	
    return con.update(queryVector);
  }
	
  /** check whether the concept exists or not
   * @return boolean representing the result of operation
   **/	
  public boolean isExistent() {
		
    String sql = "SELECT * FROM LMT_DEFINITIONS WHERE ";
    sql += " concept_id = '" + concept_id + "'";
    sql += " AND definition_id = '" + definition_id + "'";
				
    return con.isExistent(sql);
  }

  /** check whether the defintion has only one cte
   * @return boolean representing the result of operation
   **/		
  public boolean isCteSelected() {
		
    String sql = "SELECT * FROM LMT_DEFINITIONS ";
    sql += " WHERE concept_id = '" + concept_id + "'";
    sql += " AND cte_usage = 'T'";
    sql += " AND NOT(definition_id = '" + definition_id + "')";
		
    Debug.debug("-- isOneCte : " + sql);	
		
    return con.isExistent(sql);
  }	
	
  /** make the query using input vector
   * @param comVector	vector which has objects of this class
   * @return String[] array including SQL
   **/	
  public static void makeQuery(Vector queryVector, Vector defVector) {
    if (defVector == null)
      return;
		
    String query;
    for ( int i=0; i<defVector.size(); i++) {
      Definition d = (Definition)defVector.elementAt(i);
      query = "UPDATE LMT_DEFINITIONS SET";
      query += " usage_definition = '" + Util.replaceSingleQuote(d.getUsageDefinition()) + "',";
      query += " cte_usage = '" + d.getCteUsage() + "'";
      query += " WHERE concept_id = '" + d.getConceptID() + "'";
      query += " AND definition_id = '" + d.getDefinitionID() + "'";
      //Debug.debug("-- update Definition: " + query);
      queryVector.addElement(query);
    }
  }	
	
  public String makeInsertQuery() {
    String sql = "INSERT INTO LMT_DEFINITIONS VALUES (";
    sql += "'" + definition_id + "',";
    sql += "'" + concept_id + "',";
    sql += "'" + usage_definition + "',";
    sql += "'" + cte_usage + "',";
    sql += "'" + audience + "',";
    sql += "'" + active + "')";
    return sql;
  }		
}

