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.Collections;
import java.util.LinkedHashSet;
import java.util.ListIterator;
import java.util.Set;

public class GenerateHtml_class_doc 
{
	private final int          classesWithTwoSuperclasses = 9 ;
    private       Connection   DBconnection               = null ;
    private       DBFO_DButils dbu                        = new DBFO_DButils() ;
	
	GenerateHtml_class_doc(String      htmlResult,   //  result file name 
                           Connection  DBconnection  //  DB connections
                          )
    {
		this.DBconnection = DBconnection ;
    //    this.rels = new RelationsFetcher(DBconnection).getRelations() ;
		
        int        countOfHtmlClasses = 0 ;
        FileWriter fileWriter         = null ;

        try 
        { 
            ArrayList<String>  classes = dbu.getListOfClasses(this.DBconnection);
            /**
             *  These classes ('classesWithTwoSuperclasses') have two superclasses:
             *  one from the SO-structure, and one from the BFO 2020. This is the
             *  reason, why they are two times in the DB. To compute the correct 
             *  number of classes this number classes.size() must be decremented
             *  with 'classesWithTwoSuperclasses'. 
             */
            int numofClasses = classes.size() - classesWithTwoSuperclasses ;

            fileWriter = new FileWriter(new File(htmlResult), true) ;
           
            fileWriter.write(createButton("closeAllDropDownWindow", "Close all drop down windows")) ;
            
            fileWriter.write("<div class=\"class-name\" onclick=\"toggleDetails(this)\">\n") ;
                fileWriter.write("    <div class=\"h4p\">Classes (" + numofClasses + ")</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) ;
            // Remove duplicates while preserving order
            Set<String> uniqueClasses = new LinkedHashSet<>(classes);
            classes = new ArrayList<>(uniqueClasses);
            Collections.sort(classes, Collections.reverseOrder());
            Collections.reverse(classes);

            ListIterator<String> itr = classes.listIterator();            
            
            while (itr.hasNext())
            {
         	   fileWriter.write(compileClassDocumentation(itr.next())) ;
         	   countOfHtmlClasses++ ;
            }
           
            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  " + countOfHtmlClasses + 
                    		  " html class-description(s)\n")
                      .toString()
                 ) ; 
    	
    }   //  end of constructor()

	
	private String compileClassDocumentation(String class_IRI)
	{
		String[] classAnnotation    = dbu.getClassAnnotation(class_IRI, this.DBconnection) ;
		String annotation           = classAnnotation[0] ;
        String annotation_type_IRI  = classAnnotation[1] ;
        String language             = classAnnotation[2] ;

        String subclasses           = getSubclasses(class_IRI) ; 
        String superclasses         = getSuperclasses(class_IRI) ; 
        String BFOsuperclass        = getBFOsuperclass(class_IRI) ;
        String disjunctSuperclasses = getDisjointClasses(class_IRI) ;
        
        String quickSelectAddress   = "<a name=\"" + getQickSelectAddress(class_IRI)  +  "\">" ;
        
        String htmlCmd = quickSelectAddress +
        "<a name=\"" + class_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;" + class_IRI + "\n" + 
        "        </h3>\n" +
        "    </div>\n" +
        "</div>\n" +
        
        "<div class=\"class-details\">" +
        "    <b>Annotation:</b> " + annotation +               "\n" +
        "        <span class=\"smallest\"><br /></span>         \n" +
        "    <b>Annotation source:</b> (editor)                 \n" + 
        "        <span class=\"smallest\"><br /></span>         \n" +
        "    <b>Annotation type:</b> " + annotation_type_IRI + "\n" +
        "        <span class=\"smallest\"><br /></span>         \n" +
        "    <b>Language:</b> " + language +                   "\n" +
        "        <span class=\"smallest\"><br /></span>         \n" +
             subclasses +
        "        <span class=\"smallest\"><br /></span>         \n" +
        "    <b>Superclass(es):</b> " + superclasses +         "\n" +
        "        <span class=\"smallest\"><br /></span>         \n" +
        "         <b>BFO 2020 Superclass:</b> " +
        "<a href=\"https://www.ebi.ac.uk/ols4/ontologies/bfo/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252F" + BFOsuperclass + "/\" target=\"_blank\">" + BFOsuperclass + "</a>\n" +   
        "        <span class=\"smallest\"><br /></span>         \n" +
        "        <span class=\"smallest\"><br /></span>         \n" +
             disjunctSuperclasses + "\n<p />" +
        "</div>\n" ;

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

	private String getSuperclasses(String class_IRI)
	{
		String result = "";
		
        ArrayList<String> superClasses = dbu.getSuperclass(class_IRI, this.DBconnection) ; 
        ListIterator<String> itr = superClasses.listIterator() ;
		
        int    cnt               = 1 ;
        int    numofSuperclasses = superClasses.size() ;
        String currentSuperclass = "" ;
        
        while (itr.hasNext())
        {
        	currentSuperclass = itr.next() ;
        	
            if (cnt == 1)
                result += "<a href=\"#" + currentSuperclass + "\">" + currentSuperclass + "</a>";
            else
            	result += (currentSuperclass) ;

            if (cnt < numofSuperclasses)
                 result += ", " ;
            
            cnt++ ;
        }
        
        return result ;
		
	}   //  end of method getSuperclasses()
	
	private String getSubclasses(String class_IRI)
	{
		String result = "";

		ArrayList<String> subClasses = dbu.getSubclasses(class_IRI, this.DBconnection) ; 
		Collections.sort(subClasses);
        ListIterator<String> itr = subClasses.listIterator() ;
		
        int    cnt             = 1 ;
        int    numofSubclasses = subClasses.size();
        
        while (itr.hasNext())
        {
        	if (cnt > 1)
        	{
        	    result += ("<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " +
        	               "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;") ;
        	}
            String subclass = itr.next() ;      	
            result += "<a href=\"#" + subclass + "\">" + subclass + "</a>";
        	
        	if (cnt < numofSubclasses)
                result += ", " ;
            
            cnt++ ;
        }

        if (result.length() == 0) 
        	result = "&mdash;" ;
        
        return "         <b>Subclass(es):</b> " + result ;
		
	}   //  end of method getSubclasses()
	
	private String 	getDisjointClasses(String class_IRI)
	{
		String result = "";

		ArrayList<String> disjointClasses = dbu.getDisjointClasses(class_IRI, this.DBconnection) ; 
		Collections.sort(disjointClasses);
		
		ListIterator<String> itr = disjointClasses.listIterator() ;
		
        int    cnt                  = 1 ;
        int    numofDisjointclasses = disjointClasses.size();
        
        while (itr.hasNext())
        {
        	if (cnt > 1)
        	{
        	    result += ("<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " +
        	               "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ") ;
        	}
        	
            String disjointClass = itr.next() ;      	
            result += "<a href=\"#" + disjointClass + "\">" + disjointClass + "</a>";
            
        	if (cnt < numofDisjointclasses)
                result += ", " ;
            
            cnt++ ;
        }

        if (result.length() == 0) 
        	result = "&mdash;" ;
      
        return "         <b>Disjoint class(es):</b> " + result ;

	}   //  end of method getDisjointClasses()
	
    public String getBFOsuperclass(String class_IRI)
    {
        ArrayList<String> result = new ArrayList<String>() ; 
        ListIterator<String> itr = result.listIterator() ;
        String currItem    = "" ; 
    	
    	currItem = class_IRI ;
    	
    	for (int i = 0 ; i < 10 ; i++)
    	{
            result.clear() ;        		
            result = dbu.getSuperclass(currItem, this.DBconnection) ; 
            itr = result.listIterator() ;

            while (itr.hasNext()) 
            {
            	currItem = itr.next() ; 
                if (currItem.substring(0, 4).compareTo("BFO_") == 0) 
                	return currItem ; 
                else
                	continue ;
            }
            
            if (currItem.length() == 0)
            	return "&mdash;" ;
            
    	}   //  end of for-loop
    	
    	return "&mdash;" ; 
    	
    }   //  end of method getBFOsuperclass()

    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) ;
        	
            fileWriter.write("\n    <td valign=\"bottom\"><div class=\"custom-link-box\">" + 
                             "<a href=\"#" + address + "\"><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 class_IRI)
    {
        if (class_IRI.compareTo("Absolute_Poverty"            ) == 0) return "A" ;
        if (class_IRI.compareTo("Back_Region"                 ) == 0) return "B" ;
        if (class_IRI.compareTo("Capital_Punishment"          ) == 0) return "C" ;
        if (class_IRI.compareTo("Data_Analysis_Concepts"      ) == 0) return "D" ;
        if (class_IRI.compareTo("E-commerce"                  ) == 0) return "E" ;
        if (class_IRI.compareTo("Face-work"                   ) == 0) return "F" ;
        if (class_IRI.compareTo("Gender"                      ) == 0) return "G" ;
        if (class_IRI.compareTo("Hate_Crime"                  ) == 0) return "H" ;
        if (class_IRI.compareTo("Ideal_Culture"               ) == 0) return "I" ;
        if (class_IRI.compareTo("Job_Insecurity"              ) == 0) return "J" ;
        if (class_IRI.compareTo("Kinship"                     ) == 0) return "K" ;
        if (class_IRI.compareTo("Labeling_Theory"             ) == 0) return "L" ;
        if (class_IRI.compareTo("Machismo"                    ) == 0) return "M" ;
        if (class_IRI.compareTo("Nation"                      ) == 0) return "N" ;
        if (class_IRI.compareTo("Obedience"                   ) == 0) return "O" ;
        if (class_IRI.compareTo("Participant_Observation"     ) == 0) return "P" ;
        if (class_IRI.compareTo("Qualitative_Research"        ) == 0) return "Q" ;
        if (class_IRI.compareTo("Racial_Group"                ) == 0) return "R" ;
        if (class_IRI.compareTo("Sacred"                      ) == 0) return "S" ;
        if (class_IRI.compareTo("Teacher-expectancy_Effect"   ) == 0) return "T" ;
        if (class_IRI.compareTo("Unconscious"                 ) == 0) return "U" ;
        if (class_IRI.compareTo("Validity"                    ) == 0) return "V" ;
        if (class_IRI.compareTo("White-collar_Crime"          ) == 0) return "W" ;
        if (class_IRI.compareTo("Xenocentrism"                ) == 0) return "X" ;
        if (class_IRI.compareTo("Youth_Culture"               ) == 0) return "Y" ;
        if (class_IRI.compareTo("Zero_Population_Growth_(ZPG)") == 0) return "Z" ;
        
        return "" ;
        
    }   //  end of method getQickSelectAddress()
    
    private String createButton(String JavaScriptFunctionName, String buttonName)
    {
        return "<button onclick=\"" +   JavaScriptFunctionName + "()\"" +
                "        style=\"position: fixed;" +
                "               bottom: 10px;" +
                "               left: 710px;" +
                "               z-index: 10;" +
                "               padding: 8px 16px;" +
                "               background: white ;" +
                "               border-width: 1px;" +
                "               border-color: #0488ff;" +
                "               border-radius: 4px;" +
                "               cursor: pointer;\"><span style=\"color: #0488ff;\">Close all drop down windows</span></button>" ;

    }  //  end of method createButton()
    
}   //  end of class GenerateHtmldoc
