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_objProperties_doc 
{
    private Connection                 DBconnection = null ;
    private DBFO_DButils               dbu          = new DBFO_DButils() ;
	private ArrayList<TypeOf_Relation> rels         = null ;
	
    DBFO_GenHtml_objProperties_doc(String      htmlResult,   //  result file name 
                                   Connection  DBconnection  //  DB connections
                                  )
    {
		this.DBconnection = DBconnection ;
        this.rels         = new RelationsFetcher(DBconnection).getRelations() ;
        
        int         countOfObjProperties = 0 ;
        FileWriter  fileWriter           = null ;

        try 
        { 
            ArrayList<TypeOf_ObjectProperty> objPropertyData = dbu.getListOfObjProperties(this.DBconnection) ;
            int numofObjProp = objPropertyData.size();
            
            fileWriter = new FileWriter(new File(htmlResult), true) ;

            fileWriter.write("<div class=\"class-name\" onclick=\"toggleDetails(this)\">\n") ;
                fileWriter.write("    <div class=\"h4p\">Object Properties (" + numofObjProp + ")</div>\n") ;
            fileWriter.write("</div>\n") ;

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

        /**
         *  Logging of the output volume
         */
        DBFO_main OWL2G = new DBFO_main() ;
        
        OWL2G.log(new StringBuilder()
                      .append("    asserted  " + countOfObjProperties + 
                    		  " html object property(ies)\n")
                      .toString()  
                 ) ; 
    	
    }   //  end of constructor()

	private String compileObjPropDoc(TypeOf_ObjectProperty op)
	{
		String object_property_IRI = op.object_property_IRI ;
		
		String referredRels = getReferredRelations(object_property_IRI) ; 
		
		if (referredRels.length() == 0)
            //  no relation refers this predicate (=object property)
			referredRels = "&mdash;" ;
		else
			//  emphasizing predicate (=object property) name as bold
            object_property_IRI = "<b>" + object_property_IRI + "</b>" ;
		
		String superObjProp = "<a href=\"#" + op.super_object_property_IRI + "\">" + 
                               op.super_object_property_IRI + "</a>" ; 
		
        if (op.super_object_property_IRI.compareTo("owl:topObjectProperty") == 0)
        	superObjProp = op.super_object_property_IRI  ;
		
        String quickSelectAddress = "<a name=\"" + getQickSelectAddress(op.object_property_IRI)  +  "\">" ;
        
        String htmlCmd = quickSelectAddress +
        "<a name=\"" + op.object_property_IRI  +  "\">\n" +
        
        "<span style=\"font-size: 4px;line-height: 4px;\"><p /></span>\n" +

        "<div class=\"class-name\" onclick=\"toggleDetails(this)\">\n" +
        "    <div class=\"custom-link-box\">\n" +
        "        <h3>\n" +
        "            <a href=\"#top\"><b>&uarr;</b></a>&nbsp;" + object_property_IRI + "\n" + 
        "        </h3>\n" +
        "    </div>\n" +
        "</div>\n" + 
        
        "<div class=\"class-details\">" +
        "    <b>Annotation:</b> " + op.annotation +               "\n" +
        "        <span class=\"smallest\"><br /></span>            \n" +
        
        "    <b>Annotation source:</b> (editor)                    \n" + 
        "        <span class=\"smallest\"><br /></span>            \n" +
        
        "    <b>Annotation type:</b> " + op.annotation_type_IRI + "\n" +
        "        <span class=\"smallest\"><br /></span>            \n" +
        
        "    <b>Language:</b> " + op.language +                   "\n" +
        "        <span class=\"smallest\"><br /></span>            \n"  +

        "    <b>Super object property:</b> " + superObjProp     + "\n" +
        "        <span class=\"smallest\"><br /></span>            \n" +

        "    <b>Inverse object property:</b> " + "<a href=\"#" + op.inverse_object_property_IRI + "\">" +
                                                                 op.inverse_object_property_IRI + "</a>\n" +
        "        <span class=\"smallest\"><br /></span>             \n" +
        
        "    <b>Sub-object property:</b> " + getSubObjProperties(op.object_property_IRI) + "\n" +
        "        <span class=\"smallest\"><br /></span>             \n" +
        "        <span class=\"smallest\"><br /></span>             \n" +
        
        "    <b>Referred relation(s):</b> " + referredRels + "\n" +
        "        <span class=\"smallest\"><br /></span>             \n" +
        
        "    <b>Object property characteristics:</b> " +  showObjPropCharacteristics(op) + "\n\n" +
        "        <span class=\"smallest\"><br /></span>             \n" +
        
        "</div>\n" ;

       // showObjPropAsText(op, superObjProp) ;
        
        return htmlCmd ;
		
	}   //  end of method compileClassDocumentation()
	
	
	/**
	 *  currently not used
	 */
	private boolean hasMinOneTrueFlagInTheObjPropCharacteristics(TypeOf_ObjectProperty op)
	{
        if (op.opc.ch_functional        |
            op.opc.ch_inverseFunctional |
            op.opc.ch_symmetric         |
            op.opc.ch_asymmetric        |
            op.opc.ch_transitive        |
            op.opc.ch_reflexive         |
            op.opc.ch_irReflexive
           )
           return true ;
        else
           return false ;

	}   //  end of method hasMinOneTrueFlagInTheObjPropCharacteristics()
	
	private String showObjPropCharacteristics(TypeOf_ObjectProperty op)
	{
        String table =
                "<table border=\"0\" cellpadding=\"4\">" + "\n" +
                "    <tr>" + "\n" +
                "        <td rowspan=\"2\" width=\"130px\" align=\"left\"><b>Object property characteristics:</b></td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">Functional</td>        " + "\n" +
                "        <td width=\"140px\" align=\"center\">Inverse Functional</td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">Symmetric</td>         " + "\n" +
                "        <td width=\"40px\"  align=\"center\">Asymmetric</td>        " + "\n" +
                "        <td width=\"40px\"  align=\"center\">Transitive</td>        " + "\n" +
                "        <td width=\"40px\"  align=\"center\">Reflective</td>        " + "\n" +
                "        <td width=\"40px\"  align=\"center\">Irreflective</td>      " + "\n" +
                "    </tr>" + "\n" +
                "    <tr>"  + "\n" +
                "        <td width=\"40px\"  align=\"center\">" + cvtFlagToSymbol(op.opc.ch_functional)         + "</td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">" + cvtFlagToSymbol(op.opc.ch_inverseFunctional) + "</td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">" + cvtFlagToSymbol(op.opc.ch_symmetric)         + "</td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">" + cvtFlagToSymbol(op.opc.ch_asymmetric)        + "</td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">" + cvtFlagToSymbol(op.opc.ch_transitive)        + "</td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">" + cvtFlagToSymbol(op.opc.ch_reflexive)         + "</td>" + "\n" +
                "        <td width=\"40px\"  align=\"center\">" + cvtFlagToSymbol(op.opc.ch_irReflexive)       + "</td>" + "\n" +
                "    </tr>" + "\n" +
                "</table>"  + "\n" ;
		
		return table ;
		
	}   //  end of showObjPropCharacteristics()
	
    private String cvtFlagToSymbol(boolean flag)
    {
        String result = "&ndash;" ;

        if (flag) 
        	result = "&#10004;" ;

        return result ; 

    }   //  end of method cvtFlagToSymbol()
	
	private String getSubObjProperties(String object_property_IRI)
	{
	    String result = "" ;	
	
   		ArrayList<String> subObjProps = dbu.getSubObjProperty(this.DBconnection, object_property_IRI) ; 
        ListIterator<String> itr = subObjProps.listIterator();            
        String subObjectProp = "" ;
        while (itr.hasNext())
        {
            //  getting a sub object property
        	subObjectProp = itr.next() ;
        	
            //  build anchor from that
            subObjectProp = "<a href=\"#" + subObjectProp + "\">" + subObjectProp + "</a>, " ;

            //  add to the result
            result += "<br />&nbsp; &nbsp; &nbsp; &nbsp; " + subObjectProp + "\n";   // !!!!
	    }
        
        if (result.length() == 0)
        	result = "&mdash;" ;
        else
            //  cutting of the last " ," 
            if (result.length() > 0)
                result = result.substring(0, result.length() - 2) ;		

        return result ;
        
	}   //  end of method getSubObjProperties()

    private void generateSelectorTable(FileWriter fileWriter) throws IOException
    {
        fileWriter.write("<table border=\"0\" cellspacing=\"0px\" cellpadding=\"0px\">") ;
        fileWriter.write("<tr class=\"TOC\">") ;

        //                   A               Z
        for (int anchor = 0x41 ; anchor <=0x5A ; anchor++)
        {
        	char letter = (char)anchor ;
        	String address = Character.toString(letter) ;
        	
        	if      (address.compareTo("J") == 0)  address = "_" ;
        	else if (address.compareTo("Q") == 0)  address = "_" ;
        	else if (address.compareTo("X") == 0)  address = "_" ;
        	else if (address.compareTo("Y") == 0)  address = "_" ;
        	else if (address.compareTo("Z") == 0)  address = "_" ;
        	
            fileWriter.write("\n    <td valign=\"bottom\"><div class=\"custom-link-box\">" + 
                             "<a href=\"#" + address + "_op\"><h3>&nbsp;" + address + 
                             "&nbsp;</h3></a></div></div></td>") ;
        }

        fileWriter.write("\n</tr>") ;
        fileWriter.write("\n</table>\n") ;
        fileWriter.write("<span style=\"line-height: 8px;\"><br /></span>\n\n") ;
        
    }   //  end of method generateSelectorTable()

    private String getQickSelectAddress(String objPropName)
    {
        if (objPropName.compareTo("adjudicatedBy"               ) == 0) return "A_op" ;
        if (objPropName.compareTo("belongsTo"                   ) == 0) return "B_op" ;
        if (objPropName.compareTo("caredForBy"                  ) == 0) return "C_op" ;
        if (objPropName.compareTo("delegatedBy"                 ) == 0) return "D_op" ;
        if (objPropName.compareTo("E-economicallyRelatedTo"     ) == 0) return "E_op" ;
        if (objPropName.compareTo("followsCharismaticLeader"    ) == 0) return "F_op" ;
        if (objPropName.compareTo("gentrifiedBy"                ) == 0) return "G_op" ;
        if (objPropName.compareTo("hasAuthority"                ) == 0) return "H_op" ;
        if (objPropName.compareTo("identifiedBy"                ) == 0) return "I_op" ;
        // no "J" letter
        if (objPropName.compareTo("kinRelatedTo"                ) == 0) return "K_op" ;
        if (objPropName.compareTo("leadsActivity"               ) == 0) return "L_op" ;
        if (objPropName.compareTo("managedBy"                   ) == 0) return "M_op" ;
        if (objPropName.compareTo("negotiatesWith"              ) == 0) return "N_op" ;
        if (objPropName.compareTo("observedBy"                  ) == 0) return "O_op" ;
        if (objPropName.compareTo("participatesIn"              ) == 0) return "P_op" ;
        // no "Q" letter
        if (objPropName.compareTo("rankedBy"                    ) == 0) return "R_op" ;
        if (objPropName.compareTo("sacralizedBy"                ) == 0) return "S_op" ;
        if (objPropName.compareTo("territorializedBy"           ) == 0) return "T_op" ;
        if (objPropName.compareTo("urbanizedBy"                 ) == 0) return "U_op" ;
        if (objPropName.compareTo("validatedBy"                 ) == 0) return "V_op" ;
        if (objPropName.compareTo("weaklyTiedTo"                ) == 0) return "W_op" ;
        // no "X" letter
        // no "Y" letter
        // no "Z" letter
        
        return "" ;
        
    }   //  end of method getQickSelectAddress()

    private String getReferredRelations(String predicate)
    {
    	String result = "" ;
    	
    	for (TypeOf_Relation r : this.rels)
    	{
       	    	if (predicate.compareTo(r.predicate) == 0)
       	    	{
       	    		
       	    	    result += "<span class=\"smallest\"><br /></span>" +
       	    	    		  "<span class=\"smallest\"><br /></span>" +
       	    	    		  "&nbsp; &nbsp; &nbsp; Relation name: <b>" + r.relationName + "</b>" +
       	    	              "<br />&nbsp; &nbsp; &nbsp; " + showRelation(r) + 
       	    	              "\n"	;
       	    	}
    	}
    	
    	return result ;
    	
    }   //  end of method getReferredRelations()

    private String showRelation(TypeOf_Relation r)
    {
         String predicate = r.predicate ;

         predicate = "<a href=\"#" + predicate + "\">" + predicate + "</a>" ;
      
         String htmlCmd = "{" 
         + serializeParticipant(r.subject.size(), r.subject.listIterator())
         + "} → " + predicate + " → "
         + "<br />&nbsp; &nbsp; &nbsp; " + "{" 
         + 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      ; 
                    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 GenerateHtml_objProperties_doc 
