package OWL2generator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.ListIterator;

public class DBFO_GenHtml_n_ary_CasualRelationships 
{
	private Connection                 conn                   = null ;
    private int                        countOfCasualRelations = 0 ;
    private String                     errMsgFiller           = "    " ; 
    private String                     fatalErrorMsg          = "" ;  //  cummulated errpr messages           
	private ArrayList<TypeOf_Relation> rels                   = null ;
    private DBFO_DButils               dbu                    = new DBFO_DButils() ;
    private SharedUtils                shu                    = new SharedUtils() ;


	DBFO_GenHtml_n_ary_CasualRelationships(String htmlResult, Connection conn)
    {
        FileWriter fileWriter = null ;
        this.conn             = conn ; 

        this.rels = new RelationsFetcher(conn).getRelations() ;
        int numofRels = rels.size();
        
        try 
        { 
            fileWriter = new FileWriter(new File(htmlResult), true) ;

            fileWriter.write("\n<!--   start of N-ary Casual Relationships --->\n") ;
            fileWriter.write("<div class=\"class-name\" onclick=\"toggleDetails(this)\">\n") ;
            fileWriter.write("    <div class=\"h4p\">N-ary Casual Relationships (" 
                              + numofRels + ")</div>\n") ;
            fileWriter.write("</div>\n") ;

            fileWriter.write("<!-- start of outer drop down window content -->\n") ;
            fileWriter.write("<div class=\"class-details\">\n") ;  
            
        	ListIterator<TypeOf_Relation> itr = this.rels.listIterator() ; 
        	
            while (itr.hasNext())
            {
            	fileWriter.write(compile_n_ary_relationsDoc(itr.next())) ;
            	countOfCasualRelations++ ;
            }
            
            fileWriter.write("</div>\n") ;
    
            /**
             *  closing the buffered writer
             */
            fileWriter.close() ;
        }
        catch(IOException IOex)
        {
            IOex.printStackTrace() ;
        }

        if (this.fatalErrorMsg.length() > 0)
            shu.dsplyFatalMsgAndExit(  "Fatal error(s) detected in "
                                     + this.getClass().getSimpleName() + ":\n"
                                     + this.fatalErrorMsg 
                                     + "Cannot continue. The above errors can be corrected in\n"
                                     + "the file OWLpreprocessing/input/relationDefinitions.txt." ,  
                                     -1  //  fatal error exit code
                                    ) ;
        /**
         *  Logging of the output volume
         */
        DBFO_main OWL2G = new DBFO_main() ;
        
        OWL2G.log(new StringBuilder()
                      .append("    asserted  " + countOfCasualRelations + 
                    		  " n_ary html casual relationship(s)\n")
                      .toString()  
                 ) ; 
    	
    }   //  end of constructor()

    private String compile_n_ary_relationsDoc(TypeOf_Relation r)
    {
        String relationName       = r.relationName       ;            	
        String relationAnnotation = r.relationAnnotation ;
        String predicate          = r.predicate          ;

        /**
         *  terminology: predicate IS object property, don't forget that :)
         */
    	if (! dbu.chkObjectPropertyValidity(this.conn, predicate)) 
            this.fatalErrorMsg +=   this.errMsgFiller 
                                  + "Unknown predicate (" + predicate + ").\n" ;
        
        predicate = "<a href=\"#" + predicate + "\">" + predicate + "</a>" ;
        int    n_ary_relation_id  = r.n_ary_relation_id  ;
        String causal_event_indiv = r.causal_event_indiv ;

        String htmlCmd = 
        "<div class=\"class-name\" onclick=\"toggleDetails(this)\">\n" +
    	"    <div class=\"custom-link-box\">\n" +
    	"        <h3>\n" +
        "            <a name=\"" + relationName + "\">\n" +
    	"            <a href=\"#top\"><b>&uarr;</b></a>&nbsp;" 
    	+ relationName + "\n" + 
    	"        </h3>\n" +
    	"    </div>\n" +
    	"</div>\n" +
        "<div class=\"class-details\">\n" +
    	"<hr />\n" +
        "    <b>Annotation:</b> " + relationAnnotation + "\n" +
        "        <span class=\"smallest\"><br /></span>            \n" +

        "    <b>Parameters:</b> " + showRelation(r)  + "\n" +
        "        <span class=\"smallest\"><br /></span>            \n" +

        "    <b>Annotation source:</b> (editor)                    \n" + 
        "        <span class=\"smallest\"><br /></span>            \n" +

        "    <b>Language:</b> en \n" +
        "        <span class=\"smallest\"><br /></span>            \n"  +

        "    <b>Predicate:</b> " + predicate  + "\n" + 
        "        <span class=\"smallest\"><br /></span>            \n" +
        
        "    <b>Relation Id:</b> " + n_ary_relation_id  + "\n" +
        "        <span class=\"smallest\"><br /></span>            \n" +

        "    <b>Causal even individual:</b> " + causal_event_indiv + "\n" +
        "        <span class=\"smallest\"><br /></span>            \n" +

        compile_n_ary_Data("S u b j e c t (s)", r.subject.listIterator()) +
        compile_n_ary_Data("O b j e c t (s)"  , r.object .listIterator()) +

        "</div>\n" ;
        
        return htmlCmd ;    	

    }   //  end of method compile_n_ary_relationsDoc()
    
    private String compile_n_ary_Data(String title,
    		                          ListIterator<TypeOf_Relation.RelationMemberData> itr)
    {
        String htmlCmd = 
        "        <span class=\"smallest\"><br /></span>                \n" +
        "    <b>" + title + "</b><br />\n" ;
        
        while (itr.hasNext())
        {
        	TypeOf_Relation.RelationMemberData x = itr.next() ;

            String class_name = x.OWLclassName      ; 
            
            if (! dbu.chkClassNameValidity(this.conn, class_name)) 
            	this.fatalErrorMsg +=   this.errMsgFiller 
            	                      + "Unknown class name ("+ class_name + ").\n" ;
            
              class_name = "<a href=\"#" + class_name + "\">" 
            + class_name + "</a>" ;
            
            String data_property_name = x.dataPropertyName ;
            if (data_property_name != null) 
            {
            	if (! dbu.chkDataPropertyValidity(this.conn, data_property_name))
            		this.fatalErrorMsg +=   this.errMsgFiller 
            		                      + "Unknown data property name (" 
                                          + data_property_name + ").\n" ;

            	data_property_name = "<a href=\"#" + data_property_name + "\">" 
                 + data_property_name + "</a>" ;
            }
            else
            	data_property_name = "&mdash;" ;

            String data_property_value = x.dataPropertyValue ;
            String data_property_type  = dbu.getDataPropertyType(this.conn, 
            		                                             x.dataPropertyName) ;
            if ( data_property_value == null || 
                (data_property_value = data_property_value.trim()).isEmpty() || 
                 data_property_value.equalsIgnoreCase("null")
               )
            {
                data_property_value = "&mdash;" ;
            }
            else
            {
            	ChkDataPropertyValueConsistency cpvc = new ChkDataPropertyValueConsistency() ;
            	if (cpvc.check(data_property_value, data_property_type) == false)
                {
            		this.fatalErrorMsg +=   this.errMsgFiller 
		                      + "data property value/type inconsistency: '" 
		                      +  data_property_value + "' does not conform with " 
		                      +  data_property_type + ").\n" 
		                      +  "OWL class name is " + x.OWLclassName + ", " 
		                      +  "data_property_name is " + x.dataPropertyName + ".\n" ; 
                }
            	
            }

            if (data_property_type.length() == 0)
                data_property_type = "&mdash;" ;
            
            int    participant_id       = x.participant_id    ;
            int    n_ary_relation_id    = x.n_ary_relation_id ;

            htmlCmd +=         	
            "        <span class=\"smallest\"><br /></span>            \n" +
            "    <i>Class name:</i> " + class_name  + "\n"   +
            "        <span class=\"smallest\"><br /></span>            \n" +

            "    <i>Data property name:</i> " + data_property_name  + "\n" +
            "        <span class=\"smallest\"><br /></span>            \n" +

            "    <i>Data property value:</i> " + data_property_value  + "\n" +
            "        <span class=\"smallest\"><br /></span>            \n" +

            "    <i>Data property type:</i> " + data_property_type  + "\n" +
            "        <span class=\"smallest\"><br /></span>            \n" +

            "    <i>Participant Id:</i> " + participant_id  + "\n" +
            "        <span class=\"smallest\"><br /></span>            \n" +

            "    <i>Relation Id:</i> " + n_ary_relation_id  + "\n" +
            "        <span class=\"smallest\"><br /></span>            \n" ;
        
        }   //  end of while-loop

        return htmlCmd ;    
        
   }   //  end of method compile_n_ary_subjectData()
    
    private String showRelation(TypeOf_Relation r)
    {
        String predicate          = r.predicate          ;

       	if (! dbu.chkObjectPropertyValidity(this.conn, predicate)) 
            this.fatalErrorMsg +=   this.errMsgFiller 
                                  + "Unknown predicate (" + predicate + ").\n" ;
        
        predicate = "<a href=\"#" + predicate + "\">" + predicate + "</a>" ;
 	
        String htmlCmd = "{" 
        + serializeParticipant(r.subject.size(), r.subject.listIterator())
        + " → " + predicate 
        + " → " 
        + serializeParticipant(r.object.size(), r.object.listIterator())
        + "}" ;

        return htmlCmd ; 
    	
    }   //  end of method showRelation()

    private String serializeParticipant(int arraySize, 
    	                                ListIterator<TypeOf_Relation.RelationMemberData> itr)
    {
        String htmlCmd    = "" ;
        int numofSubjects = 0 ;

        while (itr.hasNext())
        {
        	TypeOf_Relation.RelationMemberData x = itr.next() ;

            String class_name = x.OWLclassName      ; 
            
            if (! dbu.chkClassNameValidity(this.conn, class_name)) 
            	this.fatalErrorMsg +=   this.errMsgFiller 
            	                      + "Unknown class name ("+ class_name + ").\n" ;
            
              class_name = "<a href=\"#" + class_name + "\">" 
            + class_name + "</a>" ;
            
            if (++numofSubjects < arraySize)
                htmlCmd += (class_name + ", ") ;
            else
                htmlCmd += class_name ;
        }

        return htmlCmd ;
    	
    }   //  end of method serializeParticipant()

}   //  end of class DBFO_GenHtml_dataProperties_doc 
