/**
 * Copyright 2009 Joe LaPenna
 */

package com.joelapenna.foursquare.parsers;

import com.joelapenna.foursquare.Foursquare;
import com.joelapenna.foursquare.error.FoursquareError;
import com.joelapenna.foursquare.error.FoursquareParseException;
import com.joelapenna.foursquare.types.FoursquareType;

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

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;

/**
 * @author Joe LaPenna (joe@joelapenna.com)
 */
public abstract class AbstractParser<T extends FoursquareType> implements Parser<T> {
    private static final String TAG = "AbstractParser";
    private static final boolean DEBUG = Foursquare.DEBUG;

    private static XmlPullParserFactory sFactory;
    static {
        try {
            sFactory = XmlPullParserFactory.newInstance();
        } catch (XmlPullParserException e) {
            throw new IllegalStateException("Could not create a factory");
        }
    }

    abstract protected T parseInner(final XmlPullParser parser) throws IOException,
            XmlPullParserException, FoursquareError, FoursquareParseException;

    /*
     * (non-Javadoc)
     * @see com.joelapenna.foursquare.parsers.Parser#parse(java.io.InputStream)
     */
    public final T parse(XmlPullParser parser) throws FoursquareParseException, FoursquareError {
        try {
            if (parser.getEventType() == XmlPullParser.START_DOCUMENT) {
                parser.nextTag();
            }
            return parseInner(parser);
        } catch (IOException e) {
            if (DEBUG) Log.d(TAG, "IOException", e);
            throw new FoursquareParseException(e.getMessage());
        } catch (XmlPullParserException e) {
            if (DEBUG) Log.d(TAG, "XmlPullParserException", e);
            throw new FoursquareParseException(e.getMessage());
        }
    }

    public static final XmlPullParser createXmlPullParser(InputStream is) {
        XmlPullParser parser;
        try {
            StringBuffer sb = new StringBuffer();
            if (DEBUG) {
                while (true) {
                    final int ch = is.read();
                    if (ch < 0) {
                        break;
                    } else {
                        sb.append((char)ch);
                    }
                }
                is.close();
                Log.d(TAG, sb.toString());
            }

            parser = sFactory.newPullParser();
            parser.setInput(new StringReader(sb.toString()));
        } catch (XmlPullParserException e) {
            throw new IllegalArgumentException();
        } catch (IOException e) {
            throw new IllegalArgumentException();
        }
        return parser;
    }

    public static final XmlPullParser createXmlPullParser(String xmlString) {
        XmlPullParser parser;
        try {
            parser = sFactory.newPullParser();
            parser.setInput(new StringReader(xmlString));
        } catch (XmlPullParserException e) {
            throw new IllegalArgumentException();
        }
        return parser;
    }

    public static void skipSubTree(XmlPullParser parser) throws XmlPullParserException, IOException {
        parser.require(XmlPullParser.START_TAG, null, null);
        int level = 1;
        while (level > 0) {
            int eventType = parser.next();
            if (eventType == XmlPullParser.END_TAG) {
                --level;
            } else if (eventType == XmlPullParser.START_TAG) {
                ++level;
            }
        }
    }

}

@@ -2070,32 +2070,108 @@
 ;%0A        try %7B%0A
+            parser = sFactory.newPullParser();%0A            if (DEBUG) %7B%0A    
             Stri
@@ -2208,32 +2208,36 @@
 ();%0A            
+ 
+   
 if (DEBUG) %7B%0A   
@@ -2225,32 +2225,36 @@
    if (DEBUG) %7B%0A
+    
                 
@@ -2288,16 +2288,20 @@
         
+ 
+   
 final in
@@ -2334,24 +2334,28 @@
             
+    
 if (ch %3C 0) 
@@ -2384,15 +2384,23 @@
     
+  
+  
 break;%0A
+    
     
@@ -2448,16 +2448,20 @@
         
+  
+  
 sb.appen
@@ -2485,34 +2485,41 @@
                 
-%7D%0A
+    %7D%0A   
                 
@@ -2510,34 +2510,39 @@
                 
+ 
 %7D%0A
+    
                 
@@ -2569,16 +2569,20 @@
         
+   
+ 
 Log.d(TA
@@ -2616,58 +2616,18 @@
     
+    
 %7D
-%0A
 %0A    
-        parser = sFactory.newPullParser();%0A
     
@@ -2684,32 +2684,110 @@
 ng()));%0A        
+    %7D else %7B%0A                parser.setInput(is, null);%0A            %7D%0A        
 %7D catch (XmlPull
@@ -2858,359 +2858,8 @@
 ion(
-);%0A        %7D catch (IOException e) %7B%0A            throw new IllegalArgumentException();%0A        %7D%0A        return parser;%0A    %7D%0A%0A    public static final XmlPullParser createXmlPullParser(String xmlString) %7B%0A        XmlPullParser parser;%0A        try %7B%0A            parser = sFactory.newPullParser();%0A            parser.setInput(new StringReader(xmlString)
 );%0A 
@@ -2870,37 +2870,26 @@
    %7D catch (
-XmlPullParser
+IO
 Exception e)

Fix parser construction to work even when we aren't in debug mode.