//
// Project "Portal"
//
// Michael Meyling
// Stoltenstrasse 38
// 22119 Hamburg
// Germany

package com.meyling.portal;

import java.io.*;
import java.util.*;

/**
 * Generates a HTML file from a CSV file.
 *
 * @version $Revision: 1.3 $
 * @author  Michael Meyling
 */
class PortalGenerator {

    /**
     * Erzeugt die Javaklasse DescriptionMTFields.
     * @param   args    Kommandozeilenargumente
     */
    public static void main(String[] args) {

        System.out.println("Generating \"portal.html\"..");
        generate();
    }


    /**
     * Generates a link collection HTML file out of a "database" file.
     * <p>
     * The CSV file has the following structure:
     *
     * Lines begining with "#" are comments and will be ignored.
     * Lines begining with "-" mark the begining of a new section
     * which has the name that follows after the ";".
     * All other non empty lines represent links. The first piece
     * (the text data till the first ";") is the address value, the
     * second piece (the text data after the first ";" till the end of
     * the line (or the next ";")) is the link description.
     */
    static private void generate() {

        final String name = "com/meyling/portal/portal";
        final CsvFileReader reader;
        try {
            reader = new CsvFileReader(name);
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
            return;
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return;
        }

        Complete complete = new Complete();

        String line = null;
        try {
            Topic topic = null;
            while ((line = reader.readLine()) != null && line.length() > 0) {
                if (CsvFileReader.getPiece(line, 1).equals("-")) {
                    topic = new Topic(CsvFileReader.getPiece(line, 2));
                    complete.add(topic);
                } else {
                    topic.add(new Link(CsvFileReader.getPiece(line, 1),
                        CsvFileReader.getPiece(line, 2)));
                }
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return;
        } catch (Exception e) {
            System.out.println("Error in line " + reader.getLineNumber() + ":");
            System.out.println(line);
        }

/*
        for (int i = 0; i < complete.getTopicSize(); i++) {
            final Topic topic = complete.getTopic(i);
            System.out.println("Topic=" + topic.getName());
            for (int j = 0; j < topic.getLinkSize(); j++) {
                final Link entry = topic.getLink(j);
                System.out.println("Link=" + entry.getLink() + ";" + entry.getDescription());
            }
        }
*/


        final HtmlFileWriter writer;
        try {
            writer = new HtmlFileWriter(name);
            writeHeader(writer);

            for (int i = 0; i < complete.getTopicSize(); i++) {
                final Topic topic = complete.getTopic(i);
                writer.println();
                writer.print(topic.getHtml(2));
/*
                System.out.println("Topic=" + topic.getName());
                for (int j = 0; j < topic.getLinkSize(); j++) {
                    final Link entry = topic.getLink(j);
                    System.out.println("Link=" + entry.getLink() + ";" + entry.getDescription());
                }
*/
            }

            writeTail(writer);

        } catch (IOException e) {
            System.out.println(e.getMessage());
            return;
        }
    }


    /**
     * Writes the header of the html file.
     * @param  html         where to write to
     * @throws IOException  if writing exceptions occur
     */
    private static void writeHeader(HtmlFileWriter html)
            throws IOException {
        html.println("<!doctype html public \"-//W3C//DTD HTML 2.0 //EN\">");
        html.println("<html>");
        html.println("<head>");
        html.println("<title>Michaels Portal</title>");
        html.println("<meta name=\"author\" content=\"Michael Meyling\">");
        html.println("<meta name=\"generator\" content=\"handmade\">");
        html.println("</head>");
        html.println("<body text=\"#000000\" bgcolor=\"#FFFFFF\" link=\"#FF0000\" alink=\"#FF0000\" vlink=\"#FF0000\">");
    }


    /**
     * Writes the tail of the html file.
     * @param  html         where to write to
     * @throws IOException  if writing exceptions occur
     */
    private static void writeTail(HtmlFileWriter html)
            throws IOException {
        html.println("</body>");
        html.println("</html>");
    }


    /**
     * Returns spaces.
     * @param   length       number of spaces
     * @returns <code>String</code> consisting of <code>length</code>
     *          spaces
     * @throws  IllegalArgumentException  if length > 80;
     */
    private static String space(int length)
            throws IllegalArgumentException {
        if (length > 80) {
            throw new IllegalArgumentException();
        }
        return ("                                             "
            + "                                       ")
                .substring(0, length);
    }


    /**
     * Describes an entry, consists of a link and a description.
     */
    private static class Link {

        /** HTML link */
        private final String link;

        /** link description */
        private final String description;


        /**
         * Constructs an entry.
         */
        Link(final String link, final String description) {
            if (link == null || link.length() == 0) {
                throw new IllegalArgumentException();
            }
            this.link = link;
            if (description == null || description.length() == 0) {
                this.description = link.trim();
            } else {
                this.description = description.trim();
            }
        }


        /**
         * Gets the link address.
         * @return link address
         */
        String getLink() {
            return link;
        }


        /**
         * Gets the link description.
         * @return link address
         */
        String getDescription() {
            return description;
        }


        /**
         * Gets the HTML code for this link.
         * @return HTML code
         */
        String getHtml() {
            final StringBuffer buffer = new StringBuffer();
            buffer.append("<a href=\"");
            buffer.append(link);
            buffer.append("\">");
            buffer.append(description);
            buffer.append("</a>");
            return buffer.toString();
        }
    }


    private static class Topic {

        private final String name;
        private List list = new ArrayList();

        Topic(final String name) {
            if (name == null || name.length() == 0) {
                throw new IllegalArgumentException();
            }
            this.name = name.trim();
        }


        void add(Link entry) {
            list.add(entry);
        }

        String getName() {
            return name;
        }


        Link getLink(int i) {
            return (Link) list.get(i);
        }


        int getLinkSize() {
            return list.size();
        }


        String getHtml(int offset) {
            final StringBuffer buffer = new StringBuffer();
            if (list.size() > 0) {
                buffer.append(space(offset));
                buffer.append("<h3>");
                buffer.append(name);
                buffer.append("</h3>\n");
                buffer.append(space(offset));
                buffer.append("<ul>\n");
                for (int i = 0; i < list.size(); i++) {
                    buffer.append(space(offset + 2));
                    buffer.append("<li>");
                    buffer.append(getLink(i).getHtml());
                    buffer.append("</li>\n");
                }
                buffer.append(space(offset));
                buffer.append("</ul>\n");
            }
            return buffer.toString();
        }

    }


    private static class Complete {

        private List list = new ArrayList();

        Complete () {
        }


        void add(Topic entry) {
            list.add(entry);
        }


        Topic getTopic(int i) {
            return (Topic) list.get(i);
        }


        int getTopicSize() {
            return list.size();
        }

    }


}
