/*
 * This file is part of libbluray
 * Copyright (C) 2010  William Hahne
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see
 * <http://www.gnu.org/licenses/>.
 */

package org.videolan;

import java.awt.Font;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class FontIndex extends DefaultHandler {
    public static FontIndexData[] parseIndex(String path) {
        return new FontIndex(path).getFontIndexData();
    }

    private FontIndex(String path) {
        FileInputStream stream = null;
        try {
            stream = new FileInputStream(path);
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            parser.parse(stream, this);
        } catch (FileNotFoundException e) {

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            fontData = null;
            if (stream != null) {
                try {
                    stream.close();
                } catch (Exception e) {
                }
            }
        }
    }

    public FontIndexData[] getFontIndexData() {
        return (FontIndexData[])fontDatas.toArray(new FontIndexData[fontDatas.size()]);
    }

    public void startElement (String uri, String localName, String qName, Attributes attributes)
        throws SAXException {
        if (qName.equalsIgnoreCase("fontdirectory")) {
            inDocument = true;
            return;
        }
        if (inDocument) {
            if (qName.equalsIgnoreCase("font"))
                fontData = new FontIndexData();
            else if (qName.equalsIgnoreCase("name"))
                element = ELEMENT_NAME;
            else if (qName.equalsIgnoreCase("fontformat"))
                element = ELEMENT_FORMAT;
            else if (qName.equalsIgnoreCase("filename"))
                element = ELEMENT_FILENAME;
            else if (qName.equalsIgnoreCase("style"))
                element = ELEMENT_STYLE;
            else if (qName.equalsIgnoreCase("size"))
                element = ELEMENT_SIZE;
            else
                throw new SAXException("element not supported");
            if (element == ELEMENT_SIZE) {
                for (int i = 0; i < attributes.getLength(); i++) {
                    String attrName = attributes.getQName(i);
                    if (attrName.equals("min"))
                        fontData.minSize = Integer.parseInt(attributes.getValue(i));
                    else if (attrName.equals("max"))
                        fontData.maxSize = Integer.parseInt(attributes.getValue(i));
                    else
                        throw new SAXException("invalid attribute name: " + attrName);
                }
            } else {
                if (attributes.getLength() != 0)
                    throw new SAXException("invalid attribute for state");
            }
        }
    }

    public void endElement (String uri, String localName, String qName)
        throws SAXException {
        if (qName.equalsIgnoreCase("fontdirectory")) {
            inDocument = false;
            return;
        }
        if (inDocument) {
            if (qName.equalsIgnoreCase("font")) {
                fontDatas.add(fontData);
                fontData = null;
            }
        }
        element = ELEMENT_NONE;
    }

    public void characters (char ch[], int start, int length) throws SAXException {
        switch (element) {
        case ELEMENT_NAME:
            fontData.name = new String(ch, start, length);
            break;
        case ELEMENT_FORMAT:
            fontData.format = new String(ch, start, length);
            break;
        case ELEMENT_FILENAME:
            fontData.filename = new String(ch, start, length);
            break;
        case ELEMENT_STYLE:
            String style = new String(ch, start, length);
            if (style.equals("PLAIN"))
                fontData.style = Font.PLAIN;
            else if (style.equals("BOLD"))
                fontData.style = Font.BOLD;
            else if (style.equals("ITALIC"))
                fontData.style = Font.ITALIC;
            else if (style.equals("BOLD_ITALIC"))
                fontData.style = Font.BOLD | Font.ITALIC;
            else
                throw new SAXException("invalid font style");
            break;
        }
    }

    private static final int ELEMENT_NONE = 0;
    private static final int ELEMENT_NAME = 1;
    private static final int ELEMENT_FORMAT = 2;
    private static final int ELEMENT_FILENAME = 3;
    private static final int ELEMENT_SIZE = 4;
    private static final int ELEMENT_STYLE = 5;

    private boolean inDocument = false;
    private int element = ELEMENT_NONE;
    private FontIndexData fontData = null;
    private ArrayList fontDatas = new ArrayList();
}

@@ -857,24 +857,81 @@
 dException;%0A
+import java.io.IOException;%0Aimport java.io.StringReader;%0A
 import java.
@@ -946,16 +946,16 @@
 ayList;%0A
-
 %0Aimport 
@@ -1057,16 +1057,83 @@
 ibutes;%0A
+import org.xml.sax.EntityResolver;%0Aimport org.xml.sax.InputSource;%0A
 import o
@@ -1201,16 +1201,16 @@
 ndler;%0A%0A
-
 public c
@@ -1247,16 +1247,41 @@
 Handler 
+implements EntityResolver
 %7B%0A    pu
@@ -2127,32 +2127,352 @@
 ize()%5D);%0A    %7D%0A%0A
+    public InputSource resolveEntity(String publicId, String systemId)%0A            throws SAXException, IOException %7B%0A        if (systemId.contains(%22http://www.dvb.org/mhp/dtd/fontdirectory-1-0.dtd%22)) %7B%0A            return new InputSource(new StringReader(%22%22));%0A        %7D else %7B%0A            return null;%0A        %7D%0A    %7D%0A%0A
     public void 

Fix parsing dvb.fontidex files with unreachable dtd file definition.