package org.omnetpp.neddoc;

import java.io.FileInputStream;
import java.io.InputStream;

import org.eclipse.core.runtime.IPath;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.omnetpp.common.util.FileUtils;
import org.omnetpp.ned.model.interfaces.ITypeElement;

/**
 * The default HTML version of INeddocRenderer.
 */
public class HtmlRenderer implements INeddocRenderer {

    IPath destinationPath;

    public HtmlRenderer(IPath dest) {
        destinationPath = dest;
    }

    public String appendFilenameExtension(String fileName) {
        return fileName + ".html";
    }

    public String defaultOverviewString() {
        return  "<center><h1>OMNeT++ Model Documentation</h1></center>\n" +
                "<center><i>Generated from NED and MSG files</i></center>\n" +
                "<p>This documentation has been generated from NED and MSG files.</p>\n" +
                "<p>Use the links in the left frame to navigate around.</p>\n" +
                "<p>Hint for model developers: if you don\'t like this page, try creating\n" +
                "a <tt>package.ned</tt> file with the <tt>@titlepage</tt> directive\n" +
                "embedded in a comment.</p>\n"+
                "<hr/>\n" +
                "<p>Generated by neddoc.</p>";
    }

    public String copyrightNotice() {
        String atag = "<a href=\"http://creativecommons.org/licenses/by-sa/3.0\" target=\"_top\">";
        return "\n<hr><p class=\"footer\">"+atag+"<img src=\"by-sa.svg\"></a>" +
               " This documentation is released under the "+atag+"Creative Commons license</a></p>\n";
    }

    public String svgImage(String imageFileName) {
        return "<object type=\"image/svg+xml\" data=\"" + imageFileName + "\"></object>\n";
    }

    public String typeImageTag(String source) {
        return "<img src=\"" + source + "\" ismap=\"yes\" usemap=\"#type-diagram\"/>";
    }

    public String typeImageMap() {
        return "<map name=\"type-diagram\">\n";
    }

    public String areaRef(String text, String url, Rectangle bounds) {
        return "<area shape=\"rect\" href=\"" + url + "\" title=\"" + text + "\" alt=\"" + text + "\" coords=\"" + bounds.x + "," + bounds.y + "," + (bounds.x + bounds.width) + "," + (bounds.y + bounds.height) + "\">\n";
    }

    public String endTypeImageMap() {
        return "</map>\n";
    }

    public String typeSectionHeading(ITypeElement typeElement) {
        String result = "<h2 class=\"comptitle\" style=\"float: left;\">" + typeElement.getName() + "</h2>\n";

        // show a colored type label
        String typeLabel = typeElement.getReadableTagName();
        String color = "#dedede";
        if ("simple module".equals(typeLabel))
            color = "#ff000040";
        else if ("compound module".equals(typeLabel))
            color = "#00ff0040";
        else if ("network".equals(typeLabel))
            color = "#2196f340";
        else if ("channel".equals(typeLabel))
            color = "#ffca0080";
        else if (typeLabel.contains("interface"))
            color = "#00e5ff40";

        result += "<span class=\"mdl-chip\" style=\"float: right; margin-top: 6pt; background-color: "+color+";\">\n" +
                  "    <span class=\"mdl-chip__text\">"+ typeElement.getReadableTagName() +"</span>\n" +
                  "</span><div style=\"clear: both;\"/>\n";
        return result;
    }

    public String sectionHeading(String text, String clazz) {
        String result = "<h2";
        clazz = (clazz == null) ? "" : clazz;
        result += " class=\""+clazz+"\"";
        result += ">" + text + "</h2>\n";
        return result;
    }

    public String subsectionHeading(String text, String clazz) {
        String result = "<h3";
        clazz = (clazz == null) ? "" : clazz;
        result += " class=\""+clazz+"\"";
        result += ">" + text + "</h3>\n";
        return result;
    }

    public String beginSource(boolean isDarkBackground) {
    	if (isDarkBackground)
            return "<pre class=\"src dark-bg\">\n";
    	else
    		return "<pre class=\"src\">\n";
    }

    public String endSource() {
        return "</pre>\n";
    }

    public String beginTable(String clazz) {
        String result = "<table";
        if (clazz != null)
            result += " class=\""+clazz+"\"";
        result += ">\n";
        return result;
    }

    public String endTable() {
        return "</table>\n";
    }

    public String tableHeading(String ...columns) {
        String result = "   <tr>\n";
        int i = 0;
        while( i< columns.length) {
            result += "      <th";
            if (columns[i+1] != null)
                result += " class=\""+columns[i+1]+"\"";
            result += ">"+columns[i]+"</th>\n";
            i += 2;
        }
        result += "   </tr>\n";
        return result;
    }

    public String tableRow(String clazz, String ...cells) {
        String result = "   <tr";
        if (clazz != null)
            result += " class=\""+clazz+"\"";
        result += ">\n";

        for (String a : cells)
            result += "      <td>"+a+"</td>\n";
        result += "   </tr>\n";
        return result;
    }

    public String anchor(String id) {
        return "<span id=\"" + id+ "\"> </span>\n";
    }

    public String link(String text, String url, String clazz) {
        return link(text, url, clazz, null);
    }

    public String link(String text, String url, String clazz, String tooltip) {
        String result = "<a";
        if (clazz != null)
            result += " class=\""+clazz+"\"";
        if (tooltip != null)
            result += " title=\""+tooltip+"\"";
        result += " href=\""+url+"\">" + text + "</a>";
        return result;
    }

    public String paragraph(String text) {
        return "<p>" + text + "</p>\n";
    }

    public String italic(String text) {
        return "<i>" + text + "</i>";
    }

    public String bold(String text) {
        return "<b>" + text + "</b>";
    }

    public String code(String text, String clazz) {
        String result = "<code";
        if (clazz != null)
            result += " class=\""+clazz+"\"";
        result += ">" + text + "</code>";
        return result;
    }

    public String styled(String text, String clazz, TextAttribute textAttribute) {
        String result = "<span";
        if (clazz != null)
            result += " class=\""+clazz+"\"";
        if (textAttribute != null)
            result += " style=\""+styleString(textAttribute)+"\"";
        result += ">" + text + "</span>";
        return result;
    }

    public void copyStaticResources(IPath cssPath) throws Exception {
        if (cssPath == null)
            copyFileFromResource("style.css");
        else
            FileUtils.copy(new FileInputStream(cssPath.toPortableString()), destinationPath.append("style.css").toFile());

        copyFileFromResource("material.blue-light_blue.min.css");
        copyFileFromResource("material-icons.css");
        copyFileFromResource("by-sa.svg");
        copyFileFromResource("material-icons.woff2");
        copyFileFromResource("jquery.js");
        copyFileFromResource("navtree.js");
        copyFileFromResource("material.min.js");
    }

    public String getTemplateName() {
        return "material";
    }

    protected void copyFileFromResource(String resourceName) throws Exception {
        copyFileFromResource(resourceName, resourceName);
    }

    protected void copyFileFromResource(final String resourcePath, String fileName) throws Exception {
        InputStream stream = getClass().getResourceAsStream("templates/" + getTemplateName() +"/" + resourcePath);
        if (stream == null)
            throw new RuntimeException("Resource not found: " + resourcePath);
        FileUtils.copy(stream, destinationPath.append(fileName).toFile());
    }

    protected String styleString(TextAttribute textAttribute) {
        Color foregroundColor = textAttribute.getForeground();
        Color backgroundColor = textAttribute.getBackground();
        String result = "";

        if (backgroundColor != null) {
            result += "background-color: ";
            result += colorString(backgroundColor) + "; ";
        }

        if (foregroundColor != null) {
            result += "color: ";
            result += colorString(foregroundColor) + "; ";
        }

        int style = textAttribute.getStyle();

        if ((style & SWT.ITALIC) != 0)
            result += "font-style: italic; ";

        if ((style & SWT.BOLD) != 0)
            result += "font-weight: bold; ";

        return result;
    }

    protected String colorString(Color color) {
        return "#" + colorToHexString(color.getRed()) + colorToHexString(color.getGreen()) + colorToHexString(color.getBlue());
    }

    protected String colorToHexString(int number) {
        return ((number < 16) ? "0" : "") + Integer.toHexString(number);
    }

}
