/*
 * Created on Feb 17, 2004
 *
 */
package LumiSoft.UI.Controls;

import java.util.*;
import java.awt.event.*;
import javax.swing.event.*;
import LumiSoft.Data.*;

/**
 * 
 */
public class WText 
{
	private EventListenerList         m_pListners = null;
	private DataSet                   m_pDsTexts  = null;
	private Hashtable<String,DataRow> m_pTexts    = null;
	private String                    m_Language  = "";
	
	public WText(java.io.InputStream textsXmlStream,String language) throws Exception
	{
		m_pListners = new EventListenerList();
		
		m_pDsTexts = new DataSet();
		m_pDsTexts.ReadXml(textsXmlStream);
		
		ChangeLanguage(language);
	}
	
	public WText(String textsFile,String language) throws Exception
	{
		m_pListners = new EventListenerList();
		
		m_pDsTexts = new DataSet();
		m_pDsTexts.ReadXml(textsFile);
		
		ChangeLanguage(language);
	}
	
	
	/**
	 * Changes language to use.
	 * @param language
	 */
	public void ChangeLanguage(String language) throws Exception
	{
		// If specified language doesn't exist, throw exception
		if(!m_pDsTexts.getTables().get("Text").getColumns().Contains(language)){
			throw new Exception("Language '" + language + "' doesn't exist !");
		}
		
		// Construct Hashtable to specified language. Key = textID and value = text.
		m_pTexts = new Hashtable<String,DataRow>();						
		for(int i=0;i<m_pDsTexts.getTables().get("Text").getRows().getCount();i++){
			String textID = m_pDsTexts.getTables().get("Text").getRows().get(i).get("TxtID").toString();			
					
			m_pTexts.put(textID,m_pDsTexts.getTables().get("Text").getRows().get(i));
		}
		
		m_Language = language;
		
		RaiseLanguageChanged();
	}
	
	
	/**
	 * Get specified texts from local file.
	 * @param txtNumbers Text numbers, separated by ','.
	 * @return Returns DataSet containing "Text" table with one DataRowr.
	 */
	public DataSet GetTexts(String txtNumbers)
	{	
		try{
			String[] textNrs = txtNumbers.split(",");
	
			DataSet   ds = new DataSet();
			DataTable dt = ds.getTables().Add("Text");		
			
			// TODO:  currently DataTable won't support adding columns if there are some rows
			
			for(int i=0;i<textNrs.length;i++){
				String text = textNrs[i];
				
				if(m_pTexts.containsKey(text) && !dt.getColumns().Contains("T" + text) && text.length() > 0){
					dt.getColumns().Add("T" + text);
				
			//		DataRow drText = (DataRow)m_pTexts.get(text);
			//		dr.set("T" + text,drText.get(m_DefaultLanguage).toString());
				}
			}
			DataRow dr = dt.NewRow();
			for(int i=0;i<textNrs.length;i++){
				String text = textNrs[i];
				
				if(m_pTexts.containsKey(text) && dt.getColumns().Contains("T" + text) && text.length() > 0){
		//			dt.getColumns().Add("T" + text);
				
					DataRow drText = (DataRow)m_pTexts.get(text);
					dr.set("T" + text,drText.get(m_Language).toString());
				}
			}
	
			dt.getRows().Add(dr);
	
			return ds;
		}
		catch(Exception x){
			x.printStackTrace();
			return null;
		}
	}
	
	/**
	 * Gets text from expression.
	 * @param textID
	 * @return
	 */
	private String GetTextFromExpression(String textID)
	{
		String retVal = "";
		// Funny wont work with java 1.5, throws Exception 'Dangling meta caharcter ...'
	//	String[] parts = textID.split("+");
		ArrayList<String> parts = new ArrayList<String>();
		while(textID.indexOf("+") > -1){
			parts.add(textID.substring(0,textID.indexOf("+")));
			textID = textID.substring(textID.indexOf("+") + 1);
		}
		parts.add(textID);
			
		for(String part : parts){
			part = part.trim();
			if(part.startsWith("'")){
				retVal += part.substring(1,part.length() - 1); 
			}
			else{
				retVal += get(part);
			}
		}
		
		return retVal;
	}
	
	/**
	 * Gets text with specified textID and with default language.
	 * @param textID TextID or expression. Expression syntax: textID+(textID or 'free text').
	 * Examples: 15, 155+' - '+22, ... .
	 * @return
	 */
	public String get(String textID)
	{
		if(textID.toLowerCase().startsWith("t")){
			textID = textID.substring(1);
		}
		if(textID.indexOf("'") > -1){
			return GetTextFromExpression(textID);
		}
		
		if(!m_pTexts.containsKey(textID)){
			return "*missing";
		}
		
		DataRow dr = (DataRow)m_pTexts.get(textID);		
		if(dr.get(m_Language) != null){
			return dr.get(m_Language).toString();
		}
		else{
			return "";
		}
	}
	
	
	/**
	 * Gets supported languages.
	 * @return
	 */
	public String[] getLanguages()
	{
		String[] languages = new String[m_pDsTexts.getTables().get("Text").getColumns().getCount() - 1];
		for(int i=0;i<languages.length;i++){
			languages[i] = m_pDsTexts.getTables().get("Text").getColumns().get(i).getColumnName();
		}
		return languages;
	}
	
	
	
	/**
	 * Adds the specified action listener to receive action events
	 * from this button.
	 * @param l the action listener
	 */ 
	public void addLanguageChangedListener(ActionListener l) 
	{
		m_pListners.add(ActionListener.class,l);
	}

	/**
	 * Removes the specified action listener so it no longer receives
	 * action events from this button.
	 * @param l the action listener
	 */ 
	public void removeLanguageChangedListener(ActionListener l) 
	{
		m_pListners.remove(ActionListener.class,l);
	}
	
	/**
	 * Raises language changed event.
	 *
	 */
	private void RaiseLanguageChanged()
	{
		Object[] listeners = m_pListners.getListenerList();
		// loop through each listener and pass on the event if needed		
		for(int i=0;i < listeners.length;i++){
			if(listeners[i] == ActionListener.class){
				// pass the event to the listeners event dispatch method
				((ActionListener)listeners[i+1]).actionPerformed(new ActionEvent(this,1,""));
			}            
		}
	}
}
