/*
 * @(#) SearchLevel.java  1.10 10/09/02
 *
 * Copyright ***,  All Rights Reserved.
 * 
 * This software is the proprietary information of ********  
 * Use is subject to license terms.
 * 
 */

// import java packages
//
import java.io.*;
import java.lang.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;

/**
 * this class handles the implementation of search levels in program
 */
public class SearchLevel {
    
    //-----------------------------------------------------------------
    //
    // instance data members
    //
    //-----------------------------------------------------------------

    // level name
    //
    public String level_name_d;

    // graph names, set to the symbols of the upper levels
    //
    public Vector<String> graph_names_d = new Vector<String>();
    
    // this is a index to DiGraph map
    //
    public HashMap<String,DiGraph> graphs_d = new HashMap<String,DiGraph>();
    public HashMap work_areas_d = new HashMap();
    public Vector symbol_types_d = new Vector();

    // different symbol tables
    //
    public Vector<String> symbols_d = new Vector<String>();
    public Vector<String> contexts_d = new Vector<String>();
    public Vector<String> non_speech_d = new Vector<String>();
    public Vector<String> contextless_d = new Vector<String>();
    public Vector<String> dummy_d = new Vector<String>();
    public Vector<String> skip_d = new Vector<String>();
    public Vector<String> exclude_d = new Vector<String>();    
    public Vector<String> nonspeechboundary_d = new Vector<String>();
    public Vector<String> nonspeechinternal_d = new Vector<String>();
    public Vector<String> spenaltyexclude_d = new Vector<String>();
    public Vector<String> ST_d = new Vector<String>();
    
    
    // ui elements
    //
    public JPanel jGraphPane = new JPanel();
    public JScrollPane jWorkPane = 
	new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
			JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    
    //public Vector context_d;
    //public Map grammar_graph_map_d;

    //-----------------------------------------------------------------
    //
    // function members
    //
    //-----------------------------------------------------------------

    /**
     * check errors in the model
     *
     * @param prefix_a prefix to be appended to error message of CData class
     * @param msg_a    message to be appended to error message of CData class
     * 
     * @return true if data is valid
     */
    public boolean check(String prefix_a, String msg_a) {

	// print message
	//
	CData.error_message_d += prefix_a + msg_a + "\n";

	// checking the symbols
	//
	if (symbols_d.size() == 0) {
	    
	    CData.error_message_d += 
		prefix_a + CData.ERR_LEVEL_NO_SYMBOLS + "\n";
	    CData.err_flag_d = true;
	    return false;
	}
	
	// checking the graph names
	//
	if (graph_names_d.size() == 0) {
	    
          
	    CData.error_message_d += 
		prefix_a + CData.ERR_LEVEL_NO_GRAPHS + "\n";
	    CData.err_flag_d = true;
	    return false;
	}
	
	// store all graph names and graphs
	//
	CData.curr_level_index_d = 0;
	SearchLevel curr_level = 	    
	    (SearchLevel)CData.getCurrLevel();
	int k = curr_level.dummy_d.size();
	Vector<String> dummy = new Vector<String>();
        dummy = curr_level.dummy_d;
	CData.curr_level_index_d = 1;
	for (int i = 0; i < graph_names_d.size(); i++) {
	    String graph_name = (String)graph_names_d.get(i);
	    DiGraph curr_graph = (DiGraph)graphs_d.get(graph_name);
	    int m = 0; 
            int z = 0;
	    for (z = 0; z < k ; z++) {  
		
		if (graph_name == (String) dummy.get(z)) {
		    m = m + 1;
		}  
	    }  
	    if ( m == 0) {
		if ( curr_graph == null ){ 
		    
		    CData.error_message_d += 
			prefix_a + "no graph defined for: " + graph_name + "\n";
		    CData.err_flag_d = true;
		    return false;
		}
		
		String prefix = prefix_a + CData.PREFIX_INDENT;
		String message = "checking graph: " + graph_name;
	       
	    }
	}
	return true;
	
    }
    
    /**
     * initializes the global data
     * 
     */
    public void init() {
	
	// set the layout for the border
	//
	jGraphPane.setLayout(new BorderLayout());
	//jGraphPane.setPreferredSize(new Dimension(6, 10));
	jGraphPane.setLayout(new BorderLayout());
	jGraphPane.add(jWorkPane, BorderLayout.CENTER);
	
	// set the dimensions of the scroller
	//
	//jWorkPane.setBackground(Color.white);
    }
    
    /**
     * sets the work area
     * 
     * @param work_area_a WorkArea object to be used
     */
    public void setWorkArea(WorkArea work_area_a) {

	// set the layout for the border
	//
	jGraphPane.removeAll();
	//jGraphPane.setPreferredSize(new Dimension(10, 40));
	//jGraphPane.setLayout(new BorderLayout());

	JScrollPane jWorkPane = 
	    new JScrollPane(work_area_a, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
			    JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
	jGraphPane.add(jWorkPane, BorderLayout.CENTER);
	jGraphPane.revalidate();

	// set the dimensions of the scroller
	//
	//jWorkPane.setBackground(Color.white);
    }

    /**
     * Checks if symbol is a speech symbol
     * 
     * @param symbol_a possible non-speech symbol
     * @return  true if the symbol is not a speech symbol
     */
    public boolean isNonSpeechSymbol(String symbol_a) {

	if ( non_speech_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }

    /**
     * Checks if symbol is a dummy symbol
     * 
     * @param symbol_a possible dummy symbol
     * @return  true if the symbol is a dummy symbol
     */
    public boolean isDummySymbol(String symbol_a) {

	if ( dummy_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }

    /**
     * Checks if symbol is a contex-less symbol
     * 
     * @param symbol_a possible context less symbol
     * @return  true if the symbol is context-less
     */
    public boolean isContextLessSymbol(String symbol_a) {

	if ( contextless_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }

 
    /**
     * Checks if symbol is a non-speech boundary symbol
     * 
     * @param symbol_a possible non-speech boundary symbol
     * @return  true if the symbol is a non-speech bondary symbol
     */
    public boolean isNonSpeechBoundarySymbol(String symbol_a) {

	if ( nonspeechboundary_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }

   /**
     * Checks if symbol is a non-speech internal symbol
     * 
     * @param symbol_a possible non-speech internal symbol
     * @return  true if the symbol is a non-speech internal symbol
     */
    public boolean isNonSpeechInternalSymbol(String symbol_a) {

	if ( nonspeechinternal_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }

    /**
     * Checks if symbol is a spenalty exclude symbol
     * 
     * @param symbol_a possible spenalty exclude symbol
     * @return  true if the symbol is a spenalty exclude symbol
     */
    public boolean isSPenaltyExcludeSymbol(String symbol_a) {

	if ( spenaltyexclude_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }
    /**
     * Checks if symbol is a skip symbol
     * 
     * @param symbol_a possible skip symbol
     * @return  true if the symbol is a skip symbol
     */
    public boolean isSkipSymbol(String symbol_a) {

	if ( skip_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }
    /**
     * Checks if symbol is an exclude symbol
     * 
     * @param symbol_a possible exclude symbol
     * @return  true if the symbol is an exclude symbol
     */
    public boolean isExcludeSymbol(String symbol_a) {

	if ( exclude_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }

    /**
     * Checks if symbol is an STS symbol
     * 
     * @param symbol_a possible STS symbol
     * @return  true if the symbol is an STS symbol
     */
    public boolean isSTSymbol(String symbol_a) {

	if ( ST_d.indexOf(symbol_a) >= 0 ){
	    return true;
	}
	
	return false;
    }

    /**
     * Sorts the symbols
     *
     * @return true
     */
    public boolean sortSymbols() {

	Object[] symbols = symbols_d.toArray();
	Arrays.sort(symbols);
	symbols_d.clear();
	for ( int i = 0; i < symbols.length; i++ ){
	    symbols_d.add((String)symbols[i]);
	}
	return true;
    }

    /**
     * Creates the graph name with an index appended at the end of new graph
     * name
     * 
     * @return new graph name
     */
    public String createGraphName() {

	String new_name = null;
	for ( int i = 0; i < 1000000; i++ ){
	    new_name = "New Graph " + i;
	    if (!graph_names_d.contains(new_name)){
		break;
	    }
	}
	return new_name;
    }
    
    /**
     * store this level
     * 
     * @param prefix_a     prefix to append to messages
     * @param prev_level_a previous search level
     */
    
    public void store(String prefix_a, SearchLevel prev_level_a) {
	
	// get the io to set properties
	//
	Properties io = CData.io_d;
	
	// tags
	//
	String level_name_tag = prefix_a + CData.IO_LEVEL_NAME;
	String level_graph_size_tag = prefix_a + CData.IO_LEVEL_GRAPH_SIZE;
	
	// store symbol table
	//
	String level_symbol_size_tag = prefix_a + CData.IO_LEVEL_SYMBOL_SIZE;
	String level_symbol_tag = prefix_a + CData.IO_LEVEL_SYMBOL;
	CData.storeSymbols(symbols_d, level_symbol_size_tag, level_symbol_tag);
	
	// store context table
	//
	
	level_symbol_size_tag = prefix_a + CData.IO_LEVEL_CONTEXT_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_CONTEXT;
	contexts_d =checksymboltables(symbols_d, contexts_d);
	CData.storeSymbols(contexts_d, level_symbol_size_tag, level_symbol_tag);
	
	// store non_speech table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_NON_SPEECH_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_NON_SPEECH_SYMBOL;
	non_speech_d =checksymboltables(symbols_d, non_speech_d);
	CData.storeSymbols(non_speech_d, level_symbol_size_tag, level_symbol_tag);
	
	// store context_less table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_CONTEXTLESS_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_CONTEXTLESS_SYMBOL;
	contextless_d =checksymboltables(symbols_d, contextless_d);
	CData.storeSymbols(contextless_d, level_symbol_size_tag, level_symbol_tag);
	
	// store dummy table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_DUMMY_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_DUMMY_SYMBOL;
	dummy_d =checksymboltables(symbols_d, dummy_d);
	CData.storeSymbols(dummy_d, level_symbol_size_tag, level_symbol_tag);
	
	// store skip table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_SKIP_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_SKIP_SYMBOL;
	skip_d =checksymboltables(symbols_d, skip_d);
	CData.storeSymbols(skip_d, level_symbol_size_tag, level_symbol_tag);
	
	// store nonspeech boundary  table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_NONSPEECHBOUNDARY_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_NONSPEECHBOUNDARY_SYMBOL;
	nonspeechboundary_d =checksymboltables(symbols_d, nonspeechboundary_d);
	CData.storeSymbols(nonspeechboundary_d, level_symbol_size_tag, level_symbol_tag);
	
	
	// store nonspeech internal  table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_NONSPEECHINTERNAL_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_NONSPEECHINTERNAL_SYMBOL;
	nonspeechinternal_d =checksymboltables(symbols_d, nonspeechinternal_d);
	CData.storeSymbols(nonspeechinternal_d, level_symbol_size_tag, level_symbol_tag);
	
	// store spenalty exclude  table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_SPENALTYEXCLUDE_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_SPENALTYEXCLUDE_SYMBOL;
	spenaltyexclude_d =checksymboltables(symbols_d, spenaltyexclude_d);
	CData.storeSymbols(spenaltyexclude_d, level_symbol_size_tag, level_symbol_tag);
	
	
	// store exclude table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_EXCLUDE_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_EXCLUDE_SYMBOL;
	exclude_d =checksymboltables(symbols_d, exclude_d);
	CData.storeSymbols(exclude_d, level_symbol_size_tag, level_symbol_tag);
	
	// store ST table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_ST_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_ST_SYMBOL;
	ST_d =checksymboltables(symbols_d, ST_d);
	CData.storeSymbols(ST_d, level_symbol_size_tag, level_symbol_tag);
	
        
	// values
	//
	String graph_size = String.valueOf(graph_names_d.size());
	
	// store all data members
	//
	io.setProperty(level_name_tag, level_name_d);
	io.setProperty(level_graph_size_tag, graph_size);
	
	// store all graph names and graphs
	//
	for (int i= 0; i < graph_names_d.size(); i++) {
	    
	    
	    if  (prefix_a.equals("L0")) { 
		
		String graph_name = (String)graph_names_d.get(i);
		String prefix = prefix_a + CData.IO_LEVEL_GRAPH_NAME
		    + String.valueOf(i);
		io.setProperty(prefix, graph_name);
		
	       String graph_prefix = prefix_a + CData.IO_IHD_PREFIX
		   + String.valueOf(i);
	       DiGraph curr_graph = (DiGraph)graphs_d.get(graph_name);
	       
	       if ( curr_graph == null ){
		   curr_graph = new DiGraph();
		   graphs_d.put(graph_name, curr_graph);
	       }
	       curr_graph.store(graph_prefix);
	       
	    } 
		
	    else {
		
		Vector<String> symbols = new Vector<String>();
		symbols = prev_level_a.symbols_d;
		
		String graph_name = (String)symbols.get(i);
		String prefix = prefix_a + CData.IO_LEVEL_GRAPH_NAME
		    + String.valueOf(i);
		io.setProperty(prefix, graph_name);
		
		CData.curr_level_index_d = CData.curr_level_index_d + 1;
		
		String graph_prefix = prefix_a + CData.IO_IHD_PREFIX
		    + String.valueOf(i);
		
		DiGraph curr_graph = (DiGraph)graphs_d.get(graph_name);
		
		if ( curr_graph == null ){
		    curr_graph = new DiGraph();
		    graphs_d.put(graph_name, curr_graph);
		}
		curr_graph.store(graph_prefix);
		
	    }	    
	}
    }
    
    
    
    public Vector<String> checksymboltables ( Vector<String> symbols_a, Vector<String> search_symbols_a) {
	
	Vector<String> temp = new Vector<String>();
	for (int k=0; k<symbols_a.size();k++) {
	    String s = (String)symbols_a.get(k);
	    
	    for (int l=0;l<search_symbols_a.size();l++) {
		
		String ss = (String)search_symbols_a.get(l);
		if (s.equals(ss)) {       
		    temp.add(ss);
		}
	    }
	}   
	search_symbols_a = temp;
        return search_symbols_a;
    }
    
    
    
    /**
     * load this level
     * 
     * @param prefix_a prefix to be appended
     */
    public void load(String prefix_a) {

	// get the io to set properties
	//
	Properties io = CData.io_d;
	
	// tags
	//
	String level_name_tag = prefix_a + CData.IO_LEVEL_NAME;
	String level_graph_size_tag = prefix_a + CData.IO_LEVEL_GRAPH_SIZE;
	
	// values
	//
	String graph_size;
	int g_size;

	// load symbol table
	//
	String level_symbol_size_tag = prefix_a + CData.IO_LEVEL_SYMBOL_SIZE;
	String level_symbol_tag = prefix_a + CData.IO_LEVEL_SYMBOL;
	CData.loadSymbols(symbols_d, level_symbol_size_tag, level_symbol_tag);

	// load context table
	//
	level_symbol_size_tag = prefix_a + CData.IO_LEVEL_CONTEXT_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_CONTEXT;
	CData.loadSymbols(contexts_d, level_symbol_size_tag, level_symbol_tag);

	// load non_speech table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_NON_SPEECH_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_NON_SPEECH_SYMBOL;
	CData.loadSymbols(non_speech_d, level_symbol_size_tag, level_symbol_tag);

	// load context_less table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_CONTEXTLESS_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_CONTEXTLESS_SYMBOL;
	CData.loadSymbols(contextless_d, level_symbol_size_tag, level_symbol_tag);

	// load dummy table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_DUMMY_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_DUMMY_SYMBOL;
	CData.loadSymbols(dummy_d, level_symbol_size_tag, level_symbol_tag);

	// load skip table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_SKIP_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_SKIP_SYMBOL;
	CData.loadSymbols(skip_d, level_symbol_size_tag, level_symbol_tag);

	// load nonspeech boundary  table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_NONSPEECHBOUNDARY_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_NONSPEECHBOUNDARY_SYMBOL;
	CData.loadSymbols(nonspeechboundary_d, level_symbol_size_tag, level_symbol_tag);
	
	// load nonspeech internal  table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_NONSPEECHINTERNAL_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_NONSPEECHINTERNAL_SYMBOL;
	CData.loadSymbols(nonspeechinternal_d, level_symbol_size_tag, level_symbol_tag);
	
	// load spenalty exclude  table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_SPENALTYEXCLUDE_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_SPENALTYEXCLUDE_SYMBOL;
	CData.loadSymbols(spenaltyexclude_d, level_symbol_size_tag, level_symbol_tag);
	
	// load exclude table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_EXCLUDE_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_EXCLUDE_SYMBOL;
	CData.loadSymbols(exclude_d, level_symbol_size_tag, level_symbol_tag);

	// load ST table
	//
	level_symbol_size_tag = prefix_a 
	    + CData.IO_LEVEL_ST_SYMBOL_SIZE;
	level_symbol_tag = prefix_a + CData.IO_LEVEL_ST_SYMBOL;
	CData.loadSymbols(ST_d, level_symbol_size_tag, level_symbol_tag);

	// load all data members
	//
	level_name_d = io.getProperty(level_name_tag);
	graph_size = io.getProperty(level_graph_size_tag);
	g_size = Integer.valueOf(graph_size).intValue();

	// load  all graphs
	//
	for (int i= 0; i < g_size; i++) {
	    String prefix = prefix_a + CData.IO_LEVEL_GRAPH_NAME
		+ String.valueOf(i);
	    String graph_name = io.getProperty(prefix);
	    graph_names_d.add(graph_name);
	    
	    String graph_prefix = prefix_a + CData.IO_IHD_PREFIX
		+ String.valueOf(i);
	    DiGraph curr_graph = new DiGraph();
	    curr_graph.load(graph_prefix);
	    graphs_d.put(graph_name, curr_graph);
	}
	
	// initialize the search level
	//
	init();
    }
    
}






























