package consolehtmlbrowser.raisers;

import consolehtmlbrowser.events.HtmlTagParsedEvent;
import consolehtmlbrowser.listeners.HtmlDoctypeListener;
import consolehtmlbrowser.listeners.HtmlTagClosingListener;
import consolehtmlbrowser.listeners.HtmlTagParsedListener;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 *
 * @author trust56
 */
public class HtmlParser {

    private List<HtmlDoctypeListener> doctypeListeners;
    private List<HtmlTagClosingListener> tagClosingListeners;
    private List<HtmlTagParsedListener> tagParsedListeners;

    public HtmlParser() {
        doctypeListeners = new ArrayList<>();
        tagClosingListeners = new ArrayList<>();
        tagParsedListeners = new ArrayList<>();
    }

    public void addDoctypeListener(HtmlDoctypeListener doctypeListener) {
        doctypeListeners.add(doctypeListener);
    }

    public void addTagClosingListener(HtmlTagClosingListener tagClosingListener) {
        tagClosingListeners.add(tagClosingListener);
    }

    public void addTagParsedListener(HtmlTagParsedListener tagParsedListener) {
        tagParsedListeners.add(tagParsedListener);
    }

    public void parse(InputStream inputStream) {
        Scanner sc = new Scanner(inputStream);
        sc.useDelimiter("<");
        while (sc.hasNext()) {
            String tag = sc.next().trim();
            if (tag.trim().equals("")) {
                //empty lines are not interesting
            } else if (tag.startsWith("!--")) {
                //comments are not interesting
            } else if (tag.toUpperCase().startsWith("!DOCTYPE")) {
                //doctype found
                for (HtmlDoctypeListener doctypeListener : doctypeListeners) {
                    String docType = tag.substring(1, tag.length() - 2);
                    doctypeListener.doctypeFound(docType);
                }
            } else if (tag.startsWith("/")) {
                //closing tag found
                for (HtmlTagClosingListener tagClosingListener : tagClosingListeners) {
                    tagClosingListener.tagClosingFound();
                }
            } else {
                //tag opened here
                String[] tmp = tag.split(">");
                String tagItself = tmp[0];
                String content = tmp.length == 2 ? tmp[1] : "";
                tmp = tagItself.split(" ", 2);
                String tagName = tmp[0];
                String attributes = tmp.length == 2 ? tmp[1] : "";
                tmp = attributes.split("\"");
                if (tmp.length % 2 != 0 && !(tmp.length == 1 && tmp[0].equals(""))) {
//                    System.err.println("Something is wrong with an attribute list");
                    continue;
                }
                HtmlTagParsedEvent descriptor = new HtmlTagParsedEvent(this);
                descriptor.setTagName(tagName.toLowerCase());
                descriptor.setContent(content);
                for (int i = 0; i < tmp.length / 2; i++) {
                    String attributeName = tmp[i * 2].trim().replace("=", "");
                    String attributeValue = tmp[i * 2 + 1];
                    descriptor.addAttribute(attributeName.toLowerCase(), attributeValue);
                }
                for (HtmlTagParsedListener tagParsedListener : tagParsedListeners) {
                    tagParsedListener.tagParsed(descriptor);
                }
            }
        }
    }
}
