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

package lmt;

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

public class PendingTerm {
	
  public final static String STATUS_ACCEPT = "A";
  public final static String STATUS_REJECT = "R";
  public final static String STATUS_PENDING = "P";
	
  String	term_id;
  String	term_string;
  String	status;
  String	alternative;
  String	username;
  String	active;
  Vector	examples;	// vector of contexts
	
  SQLConnection con;
	
  public class Context {
    String context_id;
    String pending_term_id;
    String example;
    String active;
    Context() {
      context_id = "";
      pending_term_id = "";
      example = "";
      active = "T";	
    }
    public String getContextID() {
      return context_id;
    }	
    public void setContextID(String id) {
      if ( id == null ) id = "";
      context_id = id;
    }
    public String getExample() {
      return example;
    }	
    public void setExample(String e) {
      if ( e == null ) e = "";
      example = e;
    }
  }
	
  /** constructor 
   **/
  public PendingTerm(SQLConnection con) {
    this();
    this.con = con;
  }	

  public PendingTerm() {
    term_id = "";
    term_string = "";
    status = "";
    alternative = "";
    username = "";
    active = "";
    examples = new Vector();
  }
	
  // setters and getters
  public String getTermID() {
    return term_id;
  }	 void setTermID(String term_id) {
    if ( term_id == null )
      term_id = "";
    this.term_id = term_id;
  }	
  public String getTermString() {
    return term_string;
  }	
  public void setTermString(String term_string) {
    if ( term_string == null )
      term_string = "";
    this.term_string = term_string;
  }
  public void setStatus(String status) {
    if ( status == null )
      status = "";
    this.status = status;
  }
  public String getStatus () {
    return status;
  }
  public void setAlternative (String a) {
    if ( a == null ) a = "";		
    this.alternative = a;
  }
  public String getAlternative () {
    return alternative;
  }
  public void setUserName (String u) {
    if ( u == null ) u = "";		
    this.username = u;
  }
  public String getUserName () {
    return username;
  }
  public void setActive (String a) {
    if ( a == null ) a = "";		
    this.active = a;
  }
  public String getActive() {
    return active;
  }
  public void setExamples (Vector e) {
    this.examples = e;
  }
  public Vector getExamples() {
    return examples;
  }
  public SQLConnection getConn() {
    return con;
  }
		
  /** Get all terms which have this status
   * status can be "P" for pending terms, "A" for accepted terms, "R" for rejected terms
   * @return Vector pending terms fetched from the database.
   **/	
  public synchronized Vector fetchTerms(String status) {
    String sql = "SELECT * FROM LMT_PENDING_TERMS WHERE status = '" + status + "'";
    sql += " ORDER BY term_string";
		
    Vector termVector = new Vector();
    try {
      SQLConnection.Result r = con.query(sql);
      while (r!= null && r.hasData()){
	PendingTerm pterm = new PendingTerm(con);
	pterm.setTermID(r.rs.getString(1));				 
	pterm.setTermString(r.rs.getString(2));				 	
	pterm.setStatus(r.rs.getString(3));
	pterm.setAlternative(r.rs.getString(4));
	pterm.setUserName(r.rs.getString(5));
	pterm.setActive(r.rs.getString(6));
	pterm.setExamples(fetchExamples(pterm.getTermID()));
				
	termVector.addElement(pterm);
      }
      if (r!=null) r.close();
    } catch (SQLException E) {
      System.out.println("SQLException: " + E.getMessage());
    }		

    Debug.debug("-- fetchTerms: " + sql);		
    //Debug.debug("   size of result: " + termVector.size());
	
    return termVector;
  }
	
  private synchronized Vector fetchExamples(String tid) {
    String sql = "SELECT context_id, example FROM lmt_pending_term_contexts ";
    sql += " WHERE pending_term_id = '" + tid + "'";
		
    Vector exampleVector = new Vector();
    try {
      SQLConnection.Result r = con.query(sql);
      while (r!= null && r.hasData()){
	Context context = new Context();
	context.setContextID(r.rs.getString(1));
	context.setExample(r.rs.getString(2));
	exampleVector.addElement(context);
      }
      if (r!=null) r.close();
    } catch (SQLException E) {
      System.out.println("SQLException: " + E.getMessage());
    }		

    Debug.debug("-- getTermExamples: " + sql);		
    //Debug.debug("   size of result: " + termVector.size());
	
    return exampleVector;		
  }
	
  /** update pending term status
   * @param new status : "P" for pending terms, "A" for accepted terms, "R" for rejected terms
   * @return boolean result of change
   **/	
  public synchronized boolean updateTermStatus(String newStatus) {
		
    Debug.debug("-- updateTerm");

    // make update query
    String sql = "UPDATE LMT_PENDING_TERMS SET status = '" + newStatus +"' ";
    sql += "WHERE pending_term_id = '" + term_id +"'";
			
    Debug.debug("-- " + sql);
		
    int result = con.update(sql);
    return ( result == 1 );
  }
	
  /** update the alternative field of the pending term
   * @param new alternative
   * @return boolean result of change
   **/		
  public synchronized boolean updateAlternativeTerm(String newAlternative) {
		
    Debug.debug("-- updateTerm");

    // make update quer
    String sql = "UPDATE LMT_PENDING_TERMS SET alternative = '" + newAlternative +"' ";
    sql += "WHERE pending_term_id = '" + term_id +"'";
			
    Debug.debug("-- " + sql);
		
    int result = con.update(sql);
    return ( result == 1 );
  }	
	
  /** check whether the term exists in the LMT_PENDING_TERMS
   * @param new status : "P" for pending terms, "A" for accepted terms, "R" for rejected terms
   * @return boolean representing the result of operation
   **/	
  public boolean isExistent() {
		
    String sql = "SELECT * FROM LMT_PENDING_TERMS"; 
    sql += " WHERE term_string = '" + term_string + "'";
		
    //Debug.debug("-- isExistent : " + sql);	
    return con.isExistent(sql);
  }
	
  /** check whether the term string exists in the LMT_TERMS table
   * @return boolean representing the result of operation
   **/	
  public boolean isExistentInLMT() {
		
    String sql = "SELECT * FROM LMT_TERMS"; 
    sql += " WHERE term_string = '" + term_string + "'";
		
    //Debug.debug("-- isExistent : " + sql);	
    return con.isExistent(sql);
  }
	
  public int acceptTerm(Term term) {

    // create term id 
    String tid = con.getNewID("TERM_ID"); 
    term.setTermID(tid);
				
    // create a concept
    Concept concept = new Concept(term.getConn(), term.getPos());
    String cid = con.getNewID("CONCEPT_ID");	
    concept.setConceptID(cid);
    concept.setTermID(tid);
    concept.setCteEntry("T");
    concept.setDateCreated(Util.getTime());
    concept.setDateUpdated(concept.getDateCreated());	
    concept.setAuthorCreating(username);
    concept.setAuthorUpdating(username);	
    concept.setAmbiguity("N");
    concept.setConceptSymbol(Concept.generateConceptSymbol(term)); 

    // check duplication
    if (term.isDuplicate())	   return Constants.DUPLICATION;
    if (concept.isDuplicate()) return Constants.DUPLICATION;
		
    // create definition 
    Definition definition = new Definition(term.getConn(), cid);
    String did = con.getNewID("DEFINITION_ID");		
    definition.setConceptID(cid);
    definition.setDefinitionID(did);
    definition.setUsageDefinition("no definition");
    definition.setCteUsage("T");

		
    // create examples 
    String[] query = new String[examples.size()];
    for ( int i=0; i<query.length; i++) {
      Context context = (Context)examples.elementAt(i);
      query[i]  = "INSERT INTO LMT_EXAMPLES VALUES (";
      query[i] += "'" + con.getNewID("EXAMPLE_ID") + "',";
      query[i] += "'" + did + "',";
      query[i] += "'" + context.getExample() + "',";
      query[i] += "'T')";
    }				
		
    // make query
    String[] sql = new String[4+query.length];
    sql[0] = "UPDATE LMT_PENDING_TERMS SET status = 'A' WHERE pending_term_id = '" + term_id +"'";		
    sql[1] = term.makeInsertQuery();
    sql[2] = concept.makeInsertQuery();
    sql[3] = definition.makeInsertQuery();
    for ( int i=0; i<query.length; i++) 
      sql[i+4] = query[i];

    for (int i=0; i<sql.length; i++)
      Debug.debug("-- " + sql[i]);	
		
    boolean success = con.transaction(sql);
    return ( success ? Constants.SUCCESS : Constants.FAIL );
  }
	
  /** insert the term and concept into database
   * @return integer representing the result of operation
   **/		
  public int insert() {
    // check duplication
    if (isExistent())
      return Constants.DUPLICATION;
		
    String[] sql = new String[1+examples.size()];
		
    // query for pending term
    term_id = con.getNewID("PENDING_TERM_ID");		// get New Term ID							
    sql[0] = "INSERT INTO LMT_PENDING_TERMS VALUES (";
    sql[0] += "'" + term_id + "',";
    sql[0] += "'" + Util.replaceSingleQuote(term_string) + "',";
    sql[0] += "'" + status + "',";
    sql[0] += "'" + alternative + "',";
    sql[0] += "'" + username + "',";
    sql[0] += "'" + active + "')";

    // query for context
    for ( int i=0; i<examples.size(); i++ ) {
      Context context = (Context)examples.elementAt(i);
      context.setContextID(con.getNewID("CONTEXT_ID"));
      sql[i+1] = "INSERT INTO LMT_PENDING_TERM_CONTEXTS VALUES (";
      sql[i+1] += "'" + context.getContextID() + "',";
      sql[i+1] += "'" + term_id + "',";
      sql[i+1] += "'" + context.getExample() + "',";
      sql[i+1] += "'" + active + "')";
    }
		
    //Debug.debug("-- Term inserted : " + sql);		
		
    boolean success = con.transaction(sql);
    return ( success ? Constants.SUCCESS : Constants.FAIL );
  }
	
  /** delete this data from the table.
   * @return boolean representing the result of operation
   **/
  public boolean delete() {
    Debug.debug("-- Term deleted: term_id - " + term_id);		

    String[] sql = new String[2];
    // query for context
    sql[0]  = "DELETE FROM LMT_PENDING_TERM_CONTEXTS ";
    sql[0] += "WHERE PENDING_TERM_ID = '" + term_id + "'";

    // query for pending term
    sql[1]  = "DELETE FROM LMT_PENDING_TERMS ";
    sql[1] += "WHERE pending_term_id = '" + term_id + "'";
		
    for ( int i=0; i< sql.length; i++) 
      Debug.debug("-- sql: " + sql[i]);		
		
    return con.transaction(sql);
  }
		
  /** update this data in the table.
   * @return integer representing the result of operation
   **/
  public boolean update() {
		
    String[] sql = new String[1+examples.size()];
		
    // query for pending term
    sql[0] = "UPDATE LMT_PENDING_TERMS SET";
    sql[0] += " term_string = '" + Util.replaceSingleQuote(term_string) + "',";
    sql[0] += " status = '" + status + "',";
    sql[0] += " alternative = '" + alternative + "',";
    sql[0] += " username = '" + username + "'";
    sql[0] += " WHERE pending_term_id ='" + term_id + "'";	
		
    // query for context
    for ( int i=0; i<examples.size(); i++ ) {
      Context context = (Context)examples.elementAt(i);
      sql[i+1] = "UPDATE LMT_PENDING_TERM_CONTEXTS SET ";
      sql[i+1] += " example = '" + (String)examples.elementAt(i) + "'";
      sql[i+1] += " WHERE context_id ='" + context.getContextID() + "'";
      sql[i+1] += " AND   pending_term_id ='" + term_id + "'";	
    }
    return con.transaction(sql);
  }	
}
