/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package taskModellingTool;

import java.io.*;
import java.util.*;
import javax.swing.text.*;
import javax.swing.text.rtf.*;
import utility.*;

/** manage RTF data fields, ie, "Background",
*								"Note",
*								"Tip",
*								"Warning",
*								"Annotation" 
*	for components
*/
public class RTFManager{
	public final static String DBNAMES[]={	"Background",
										 	"Note",
										 	"Tip",
										 	"Warning",
										 	"Annotation"};
	//RTF tags
	public static final String BEGIN_BACKGROUND="(Background)";
	public static final String END_BACKGROUND="(/Background)";
	public static final String BEGIN_DESCRIPTION="(Description)";// description = note
	public static final String END_DESCRIPTION="(/Description)";
	public static final String BEGIN_TIP="(Tip)";
	public static final String END_TIP="(/Tip)";
	public static final String BEGIN_WARNING="(Warning)";
	public static final String END_WARNING="(/Warning)";
	public static final String BEGIN_ANNOTATION="(Annotation)";
	public static final String END_ANNOTATION="(/Annotation)";
	
	//XML tags
	public static final String BEGIN_BACKGROUND_XML="<Background>";
	public static final String END_BACKGROUND_XML="</Background>";
	public static final String BEGIN_DESCRIPTION_XML="<Comment>";// description = note
	public static final String END_DESCRIPTION_XML="</Comment>";
	public static final String BEGIN_TIP_XML="<Tip>";
	public static final String END_TIP_XML="</Tip>";
	public static final String BEGIN_WARNING_XML="<Warning>";
	public static final String END_WARNING_XML="</Warning>";
	public static final String BEGIN_ANNOTATION_XML="<Annotation>";
	public static final String END_ANNOTATION_XML="</Annotation>";
	
	//HTML tags
	public static final String BEGIN_BACKGROUND_HTML="<Background_HTML>";
	public static final String END_BACKGROUND_HTML="</Background_HTML>";
	public static final String BEGIN_DESCRIPTION_HTML="<Comment_HTML>";// description = note
	public static final String END_DESCRIPTION_HTML="</Comment_HTML>";
	public static final String BEGIN_TIP_HTML="<Tip_HTML>";
	public static final String END_TIP_HTML="</Tip_HTML>";
	public static final String BEGIN_WARNING_HTML="<Warning_HTML>";
	public static final String END_WARNING_HTML="</Warning_HTML>";
	public static final String BEGIN_ANNOTATION_HTML="<Annotation_HTML>";
	public static final String END_ANNOTATION_HTML="</Annotation_HTML>";

	//LISP tags
	public static final String  BACKGROUND_PREFIX="background_prefix";
	public static final String  DESCRIPTION_PREFIX="documentation_prefix";// description = note
	public static final String  TIP_PREFIX="tip_prefix";
	public static final String  WARNING_PREFIX="warning_prefix";
	public static final String  ANNOTATION_PREFIX="annotation_prefix";
	
	private TreeMap _db=new TreeMap();
	static TreeMap _tagBegin=new TreeMap(),
		_catTagBegin=new TreeMap(),
		_tagEnd=new TreeMap();
	static{
		_tagBegin.put(DBNAMES[0], BEGIN_BACKGROUND);		
		_tagBegin.put(DBNAMES[1], BEGIN_DESCRIPTION);		
		_tagBegin.put(DBNAMES[2], BEGIN_TIP);		
		_tagBegin.put(DBNAMES[3], BEGIN_WARNING);		
		_tagBegin.put(DBNAMES[4], BEGIN_ANNOTATION);
		
		_tagEnd.put(DBNAMES[0], END_BACKGROUND);		
		_tagEnd.put(DBNAMES[1], END_DESCRIPTION);		
		_tagEnd.put(DBNAMES[2], END_TIP);		
		_tagEnd.put(DBNAMES[3], END_WARNING);		
		_tagEnd.put(DBNAMES[4], END_ANNOTATION);
		
		_catTagBegin.put(BEGIN_BACKGROUND,	DBNAMES[0]);		
		_catTagBegin.put(BEGIN_DESCRIPTION,	DBNAMES[1]);		
		_catTagBegin.put(BEGIN_TIP,			DBNAMES[2]);		
		_catTagBegin.put(BEGIN_WARNING,		DBNAMES[3]);		
		_catTagBegin.put(BEGIN_ANNOTATION,	DBNAMES[4]);

	}
	
	//mapping for XML & HTML tags
	static TreeMap _tagBeginXML=new TreeMap(),
		_catTagBeginXML=new TreeMap(),
		_tagEndXML=new TreeMap(),
		_tagBeginHTML=new TreeMap(),
		_tagEndHTML=new TreeMap();
	static{
		_tagBeginXML.put(DBNAMES[0], BEGIN_BACKGROUND_XML);		
		_tagBeginXML.put(DBNAMES[1], BEGIN_DESCRIPTION_XML);		
		_tagBeginXML.put(DBNAMES[2], BEGIN_TIP_XML);		
		_tagBeginXML.put(DBNAMES[3], BEGIN_WARNING_XML);		
		_tagBeginXML.put(DBNAMES[4], BEGIN_ANNOTATION_XML)
			;		
		_tagEndXML.put(DBNAMES[0], END_BACKGROUND_XML);		
		_tagEndXML.put(DBNAMES[1], END_DESCRIPTION_XML);		
		_tagEndXML.put(DBNAMES[2], END_TIP_XML);		
		_tagEndXML.put(DBNAMES[3], END_WARNING_XML);		
		_tagEndXML.put(DBNAMES[4], END_ANNOTATION_XML);
		
		_catTagBeginXML.put(BEGIN_BACKGROUND_XML,	DBNAMES[0]);		
		_catTagBeginXML.put(BEGIN_DESCRIPTION_XML,	DBNAMES[1]);		
		_catTagBeginXML.put(BEGIN_TIP_XML,			DBNAMES[2]);		
		_catTagBeginXML.put(BEGIN_WARNING_XML,		DBNAMES[3]);		
		_catTagBeginXML.put(BEGIN_ANNOTATION_XML,	DBNAMES[4]);

		_tagBeginHTML.put(DBNAMES[0], BEGIN_BACKGROUND_HTML);		
		_tagBeginHTML.put(DBNAMES[1], BEGIN_DESCRIPTION_HTML);		
		_tagBeginHTML.put(DBNAMES[2], BEGIN_TIP_HTML);		
		_tagBeginHTML.put(DBNAMES[3], BEGIN_WARNING_HTML);		
		_tagBeginHTML.put(DBNAMES[4], BEGIN_ANNOTATION_HTML)
			;		
		_tagEndHTML.put(DBNAMES[0], END_BACKGROUND_HTML);		
		_tagEndHTML.put(DBNAMES[1], END_DESCRIPTION_HTML);		
		_tagEndHTML.put(DBNAMES[2], END_TIP_HTML);		
		_tagEndHTML.put(DBNAMES[3], END_WARNING_HTML);		
		_tagEndHTML.put(DBNAMES[4], END_ANNOTATION_HTML);
	
	}
	
	//Lisp mappings
		static TreeMap _tagPrefix=new TreeMap();
	static{
		_tagPrefix.put(DBNAMES[0], BACKGROUND_PREFIX);		
		_tagPrefix.put(DBNAMES[1], DESCRIPTION_PREFIX);		
		_tagPrefix.put(DBNAMES[2], TIP_PREFIX);		
		_tagPrefix.put(DBNAMES[3], WARNING_PREFIX);		
		_tagPrefix.put(DBNAMES[4], ANNOTATION_PREFIX);

	}

	public RTFManager (){
		for (int i = 0; i<DBNAMES.length; i++){
			_db.put(DBNAMES[i], new RTFDataBase());	
		}
	}
	
    public void add(String name) {
    	RTFDataBase db;
    	for (int i = 0; i<DBNAMES.length; i++){
			db=(RTFDataBase)_db.get(DBNAMES[i]);
			db.add(name);
		}
    }
    
    public void add(String name,String cat,DefaultStyledDocument doc) {
    	RTFDataBase db=(RTFDataBase)_db.get(cat);
		db.put(name,doc);
    }
    
    public void remove(String name) {
    	RTFDataBase db;
    	for (int i = 0; i<DBNAMES.length; i++){
			db=(RTFDataBase)_db.get(DBNAMES[i]);
			db.remove(name);
		}
    }
    
    public DefaultStyledDocument getDocument(String taskName, String cat) {
    	RTFDataBase db=(RTFDataBase)_db.get(cat);
		if (db == null) return null;
		else return db.getDocument(taskName);
    }
    
    public void changeName(String newName, String oldName) {
    	RTFDataBase db;
    	for (int i = 0; i<DBNAMES.length; i++){
			db=(RTFDataBase)_db.get(DBNAMES[i]);
			db.put(newName,(DefaultStyledDocument)db.get(oldName));
		}
    }
    
    public void writeRTF(String comName,PrintStream out) {
    	DefaultStyledDocument doc;
    	String cat;
    	RTFEditorKit kit= new RTFEditorKit();
    	for (int i = 0; i<DBNAMES.length; i++){
    		cat = DBNAMES[i];
			doc = getDocument(comName, 	cat);
			if (doc != null && doc.getLength() != 0){
				
                out.println((String)_tagBegin.get(cat));
                //kit = (RTFEditorKit)Manager.editor.textPane.getEditorKit();
                
                try {
                    kit.write(out,doc,0,doc.getLength());
                }
                catch (Exception ex) {
                }
                
                out.println();	
                out.println((String)_tagEnd.get(cat));	
                out.println();	
				
			}
    	}
    	
   	}
   	
	public void readRTF(String comName,BufferedReader in, String cat) {
		//System.out.println("now read RTF for" + cat);
		add(comName);
		String s;
    	try {
		    if (comName==null)
	        	while (!(s=in.readLine()).equals((String)_tagEnd.get(cat)));
	        else {
	        	StringBuffer buf=new StringBuffer();
	        	DefaultStyledDocument doc=new DefaultStyledDocument();
	            while (!(s=in.readLine()).equals((String)_tagEnd.get(cat))){
	                buf.append(s).append("\n");
	            }
	            ByteArrayInputStream b=new ByteArrayInputStream(buf.
	            	toString().getBytes());
	            (new RTFEditorKit()).read(b,doc,0);
	            add(comName,cat,doc);
	        }
        } catch (Exception excep)
        {System.out.println("reading RTF error in  " + cat+ " :"+ excep);}
	}
	  
    public void writeRTF_XML(String comName,PrintStream out) {
    	DefaultStyledDocument doc;
    	String cat;
    	RTFEditorKit kit= new RTFEditorKit();
    	for (int i = 0; i<DBNAMES.length; i++){
    		cat = DBNAMES[i];
			doc = getDocument(comName, 	cat);
			if (doc != null && doc.getLength() != 0){
				
                out.println((String)_tagBeginXML.get(cat));
                //kit = (RTFEditorKit)Manager.editor.textPane.getEditorKit();
                
                try {
                    kit.write(out,doc,0,doc.getLength());
                }
                catch (Exception ex) {
                }
                
                out.println();	
                out.println((String)_tagEndXML.get(cat));	
                out.println();	
				
			}
    	}
    	
   	}
	  
    public void writeRTF_HTML(String comName,PrintStream out) {
    	final String BEGIN_BODY = "<body>";
        final String END_BODY = "</body>";       
        final int lbb = BEGIN_BODY.length();
        final int leb = END_BODY.length();
        CharArrayWriter tempOut;
        BufferedReader tempIn;
        MinimalHTMLWriter2 w;   // modify MinimalHTMLWriter in order to fix its bug

    	DefaultStyledDocument doc;
    	String cat;
    	RTFEditorKit kit= new RTFEditorKit();
    	for (int i = 0; i<DBNAMES.length; i++){
    		cat = DBNAMES[i];
			doc = getDocument(comName, 	cat);
			if (doc != null && doc.getLength() != 0){
				out.println((String)_tagBeginHTML.get(cat));
				try{
	                tempOut = new CharArrayWriter();
		            w = new MinimalHTMLWriter2(tempOut,doc,0,doc.getLength());
		            w.write();
		
		            tempOut.close();
		            tempIn = new BufferedReader(new CharArrayReader(tempOut.toCharArray()));
		
		            String s;
		            boolean body = false;
		            boolean stop = false;
		            int l,index;
		            LinkedList tags = new LinkedList();
		            while ((s=tempIn.readLine())!=null) {
		                l=s.length()-lbb;
		                for (int j=0;j<=l;j++) {
		                    if (s.substring(j,j+lbb).equals(BEGIN_BODY)) {
		                        s=tempIn.readLine();
		                        body=true;
		                        break;
		                    }
		                }
		                l=s.length()-leb;
		                for (int j=0;j<=l;j++) {
		                    if (s.substring(j,j+leb).equals(END_BODY)) {
		                        stop=true;
		                        break;
		                    }
		                }
		                if (stop) break;
		                if (body) {
		                    // replace <p class=default> with <p>
		                    index = s.indexOf("<p class=default>");
		                    if (index >= 0) {
		                        s = s.substring(0,index)+"<p>";
		                    }
		
		                    // skip font tag due to its overlapping with <b>,<u>,<i> wrongly
		                    s = FileManager.skipFontTag(s);
		                    s = FileManager.skipSpanTag(s);
		                    
		                    // <b>, <u>, <i> overlap wrongly without this function
		                    // this function will open & close overlapping <b>, <u>, <i> tags properly
		                    s = FileManager.correctOverlapping_bui_Tags(s,tags);
		                    
		                    out.println(s);
		                }
		            }
		            tempIn.close();
		        }
		        catch (Exception ex) {
		        }
                out.println();	
                out.println((String)_tagEndHTML.get(cat));	
                out.println();	
			}
    	}

   	}
   	
	public void readXML(String comName,String ss,BufferedReader in, String cat) {
		//System.out.println("now read RTF from XML" + cat);
		add(comName);
		String s;
    	try {
        	StringBuffer buf=new StringBuffer();
        	DefaultStyledDocument doc=new DefaultStyledDocument();
        	s = FileManager.getElementAfterStartTagXML(ss,(String)_tagBeginXML.get(cat));
        	buf.append(s).append("\n");
            while ((s=in.readLine())!= null) {
            	if (FileManager.stringContains(s,(String)_tagEndXML.get(cat))) break;
                buf.append(s).append("\n");
            }
            ByteArrayInputStream b=new ByteArrayInputStream(buf.
            	toString().getBytes());
            (new RTFEditorKit()).read(b,doc,0);
            add(comName,cat,doc);
        } catch (Exception excep)
        {System.out.println("reading RTF error in  " + cat+ " :"+ excep);}
	}
	
    public void exportRTF(String comName,PrintStream out,
                                Hashtable mapping){
    	DefaultStyledDocument doc;
    	String cat;
    	for (int i = 0; i<DBNAMES.length; i++){
    		cat = DBNAMES[i];
			doc = getDocument(comName, 	cat);
			if (doc != null && doc.getLength() != 0){
				out.print((String)mapping.get((String)_tagPrefix.get(cat)) + " \"");
				RTFEditorKit kit =new RTFEditorKit();
                try {
                    kit.write(out,doc,0,doc.getLength());
                }
                catch (Exception ex) {
    				System.out.println("Error when exporting RTF: "+(ex.toString()));
                }
            	out.print("\"");
			}
    	}
    }
	
    public void exportASCII(String comName,PrintWriter out,
                                Hashtable mapping){
    	DefaultStyledDocument doc;
    	String cat;
    	for (int i = 0; i<DBNAMES.length; i++){
    		cat = DBNAMES[i];
			doc = getDocument(comName, 	cat);
			if (doc != null && doc.getLength() != 0){
				out.print((String)mapping.get((String)_tagPrefix.get(cat)) + " \"");
                try {
            		String str=doc.getText(0, doc.getLength());
            		str = LISPUtility.replaceDoubleQuotes(str);
            		out.print(str);	//doc.getText(0, doc.getLength()));
                }
                catch (Exception ex) {
    				System.out.println("Error when exporting RTF: "+(ex.toString()));
                }
            	out.println("\"");
			}
    	}
    }
	  
    public void exportRTF_HTML(String comName,PrintWriter out,
                                Hashtable mapping) {
    	final String BEGIN_BODY = "<body>";
        final String END_BODY = "</body>";       
        final int lbb = BEGIN_BODY.length();
        final int leb = END_BODY.length();
        CharArrayWriter tempOut;
        BufferedReader tempIn;
        MinimalHTMLWriter2 w;   // modify MinimalHTMLWriter in order to fix its bug

    	DefaultStyledDocument doc;
    	String cat;
    	RTFEditorKit kit= new RTFEditorKit();
    	for (int i = 0; i<DBNAMES.length-1; i++){ // don't export annotation
    		cat = DBNAMES[i];
			doc = getDocument(comName, 	cat);
			if (doc != null && doc.getLength() != 0){
				out.print((String)mapping.get((String)_tagPrefix.get(cat)) + " \"");
				try{
	                tempOut = new CharArrayWriter();
		            w = new MinimalHTMLWriter2(tempOut,doc,0,doc.getLength());
		            w.write();
		
		            tempOut.close();
		            tempIn = new BufferedReader(new CharArrayReader(tempOut.toCharArray()));
		
		            String s;
		            boolean body = false;
		            boolean stop = false;
		            int l,index;
		            LinkedList tags = new LinkedList();
		            while ((s=tempIn.readLine())!=null) {
		                l=s.length()-lbb;
		                for (int j=0;j<=l;j++) {
		                    if (s.substring(j,j+lbb).equals(BEGIN_BODY)) {
		                        s=tempIn.readLine();
		                        body=true;
		                        break;
		                    }
		                }
		                l=s.length()-leb;
		                for (int j=0;j<=l;j++) {
		                    if (s.substring(j,j+leb).equals(END_BODY)) {
		                        stop=true;
		                        break;
		                    }
		                }
		                if (stop) break;
		                if (body) {
		                    // replace <p class=default> with <p>
		                    index = s.indexOf("<p class=default>");
		                    if (index >= 0) {
		                        s = s.substring(0,index)+"<p>";
		                    }
		
		                    // skip font tag due to its overlapping with <b>,<u>,<i> wrongly
		                    s = FileManager.skipFontTag(s);
		                    s = FileManager.skipSpanTag(s);
		                    
		                    // <b>, <u>, <i> overlap wrongly without this function
		                    // this function will open & close overlapping <b>, <u>, <i> tags properly
		                    s = FileManager.correctOverlapping_bui_Tags(s,tags);
		                    
		                    //25-6-2002
		                    //get rid of spaces
		                    out.print(s.trim());
		                }
		            }
		            tempIn.close();
		        }
		        catch (Exception ex) {
		        }
            	out.print("\"");
                out.println();	
			}
    	}

   	}
	
    public boolean contains(String name) {
    	RTFDataBase db=(RTFDataBase)_db.get(DBNAMES[0]);
		//return (true?false:db.containsKey(name));
    	if (db.containsKey(name))
    		return true;
    	else return false;
    }
	
    public void copy(String name,RTFManager rtfm) {
    	add(name);
    	
    	DefaultStyledDocument doc;
    	for (int i = 0; i<DBNAMES.length; i++){
			doc=rtfm.getDocument(name,DBNAMES[i]);
			add(name,DBNAMES[i],doc);
		}
    }
    
    ////3-10-2001
    //generate HTML report
    public void reportRTF_HTML(String comName,PrintWriter out) {
    	final String BEGIN_BODY = "<body>";
        final String END_BODY = "</body>";       
        final int lbb = BEGIN_BODY.length();
        final int leb = END_BODY.length();
        CharArrayWriter tempOut;
        BufferedReader tempIn;
        MinimalHTMLWriter2 w;   // modify MinimalHTMLWriter in order to fix its bug

    	DefaultStyledDocument doc;
    	String cat;
    	RTFEditorKit kit= new RTFEditorKit();
    	for (int i = 0; i<DBNAMES.length; i++){ 
    		cat = DBNAMES[i];
			doc = getDocument(comName, 	cat);
			if (doc != null && doc.getLength() != 0){
				String comment = "   <FONT SIZE=\"-1\" align=\"left\"><I><B> "+cat+": </B></I></FONT>";  

				out.print(comment);
				try{
	                tempOut = new CharArrayWriter();
		            w = new MinimalHTMLWriter2(tempOut,doc,0,doc.getLength());
		            w.write();
		
		            tempOut.close();
		            tempIn = new BufferedReader(new CharArrayReader(tempOut.toCharArray()));
		
		            String s;
		            boolean body = false;
		            boolean stop = false;
		            int l,index;
		            LinkedList tags = new LinkedList();
		            while ((s=tempIn.readLine())!=null) {
		                l=s.length()-lbb;
		                for (int j=0;j<=l;j++) {
		                    if (s.substring(j,j+lbb).equals(BEGIN_BODY)) {
		                        s=tempIn.readLine();
		                        body=true;
		                        break;
		                    }
		                }
		                l=s.length()-leb;
		                for (int j=0;j<=l;j++) {
		                    if (s.substring(j,j+leb).equals(END_BODY)) {
		                        stop=true;
		                        break;
		                    }
		                }
		                if (stop) break;
		                if (body) {
		                    // replace <p class=default> with <p>
		                    index = s.indexOf("<p class=default>");
		                    if (index >= 0) {
		                        s = s.substring(0,index)+"<p>";
		                    }
		
		                    // skip font tag due to its overlapping with <b>,<u>,<i> wrongly
		                    s = FileManager.skipFontTag(s);
		                    s = FileManager.skipSpanTag(s);
		                    
		                    // <b>, <u>, <i> overlap wrongly without this function
		                    // this function will open & close overlapping <b>, <u>, <i> tags properly
		                    s = FileManager.correctOverlapping_bui_Tags(s,tags);
		                    
		                    out.println(s);
		                }
		            }
		            tempIn.close();
		        }
		        catch (Exception ex) {
		        }
            //	out.print("\"");
                out.println();	
			}
    	}

   	}
	
}