package com.mapzen.tangram;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;
import android.util.Log;

class FontFileParser {

    private Map<String, String> fontDict = new HashMap<String, String>();

    private void processDocument(XmlPullParser parser) throws XmlPullParserException, IOException {

        parser.nextTag();
        // Parse Families
        parser.require(XmlPullParser.START_TAG, null, "familyset");
        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            if ("family".equals(parser.getName())) {
                // Parse this family:
                String name = parser.getAttributeValue(null, "name");
                while (parser.next() != XmlPullParser.END_TAG) {
                    if (parser.getEventType() != XmlPullParser.START_TAG) {
                        continue;
                    }
                    String tag = parser.getName();
                    if ("font".equals(tag)) {
                        String weightStr = parser.getAttributeValue(null, "weight");
                        weightStr = (weightStr == null) ? "400" : weightStr;

                        String styleStr = parser.getAttributeValue(null, "style");
                        styleStr = (styleStr == null) ? "normal" : styleStr;

                        String filename = parser.nextText();
                        String fullFilename = "/system/fonts/" + filename;

                        String key = name + "_" + weightStr + "_" + styleStr;
                        fontDict.put(key, fullFilename);
                    } else {
                        skip(parser);
                    }
                }
            } else if ("alias".equals(parser.getName())) {
                // Parse this alias to font to fileName
                String aliasName = parser.getAttributeValue(null, "name");
                String toName = parser.getAttributeValue(null, "to");
                String weightStr = parser.getAttributeValue(null, "weight");
                weightStr = (weightStr == null) ? "400" : weightStr;
                String fontFilename = fontDict.get(toName + "_" + weightStr + "_normal"); // alias style is default: normal (always)
                fontDict.put(aliasName + "_" + weightStr, fontFilename);
            } else {
                skip(parser);
            }
        }
    }

    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        int depth = 1;
        while (depth > 0) {
            switch (parser.next()) {
            case XmlPullParser.START_TAG:
                depth++;
                break;
            case XmlPullParser.END_TAG:
                depth--;
                break;
            }
        }
    }

    public FontFileParser() {

        InputStream in = null;
        final File fontFile = new File("/system/etc/fonts.xml");

        // TODO: Handle system_fonts parsing which has a different xml layout as compared to fonts.xml
        //       system_fonts.xml also does not seem to have a good css style font parameter mapping as is the case with
        //       fonts.xml (fonts.xml is available in android L and above)

        String fileXml = "";

        if (fontFile.exists()) {
            fileXml = fontFile.getAbsolutePath();
        }

        if("".equals(fileXml)) {
            return;
        }

        try {
            in = new FileInputStream(fileXml);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return;
        }

        XmlPullParser parser = Xml.newPullParser();

        try {
            parser.setInput(in, null);
            processDocument(parser);
        } catch(XmlPullParserException e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }

        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getFontFile( String _key ) {
        if (fontDict.containsKey(_key)) {
            return fontDict.get(_key);
        } else {
            return "";
        }
    }

}


@@ -216,16 +216,41 @@
 til.Map;
+%0Aimport java.util.Vector;
 %0A%0Aimport
@@ -574,24 +574,80 @@
 xception %7B%0A%0A
+        Vector%3CString%3E weights = new Vector%3CString%3E();%0A%0A
         pars
@@ -1456,32 +1456,107 @@
 ull, %22weight%22);%0A
+                        if (weightStr != null) %7B weights.add(weightStr); %7D%0A
                 
@@ -2514,50 +2514,245 @@
     
-weightStr = (weightStr == null) ? %22400%22 : 
+Vector%3CString%3E aliasWeights = new Vector%3CString%3E();%0A                String fontFilename;%0A%0A                if (weightStr == null) %7B%0A                    aliasWeights = weights;%0A                %7D else %7B%0A                    aliasWeights.add(
 weig
@@ -2756,16 +2756,17 @@
 eightStr
+)
 ;%0A      
@@ -2779,197 +2779,626 @@
     
-String fontFilename = fontDict.get(toName + %22_%22 + weightStr + %22_normal%22); // alias style is default: normal (always)%0A                fontDict.put(aliasName + %22_%22 + weightStr, fontFilename);
+%7D%0A%0A                for (int i = 0; i %3C aliasWeights.size(); ++i) %7B%0A                    // Only 2 styles possible based on /etc/fonts.xml%0A                    // Normal style%0A                    fontFilename = fontDict.get(toName + %22_%22 + aliasWeights.get(i) + %22_normal%22);%0A                    fontDict.put(aliasName + %22_%22 + aliasWeights.get(i) + %22_normal%22, fontFilename);%0A                    // Italic style%0A                    fontFilename = fontDict.get(toName + %22_%22 + aliasWeights.get(i) + %22_italic%22);%0A                    fontDict.put(aliasName + %22_%22 + aliasWeights.get(i) + %22_italic%22, fontFilename);%0A                %7D
 %0A   

Update Android FontFileParser