/**
 *  Copyright 2011 Ryszard Wiśniewski <brut.alll@gmail.com>
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package brut.androlib.res.decoder;

import brut.androlib.AndrolibException;
import brut.androlib.res.AndrolibResources;
import brut.androlib.res.data.ResTable;
import brut.androlib.res.util.ExtXmlSerializer;
import java.io.*;
import java.util.logging.Logger;

import org.xmlpull.v1.*;
import org.xmlpull.v1.wrapper.*;
import org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper;

/**
 * @author Ryszard Wiśniewski <brut.alll@gmail.com>
 */
public class XmlPullStreamDecoder implements ResStreamDecoder {
    public XmlPullStreamDecoder(XmlPullParser parser,
            ExtXmlSerializer serializer) {
        this.mParser = parser;
        this.mSerial = serializer;
    }

    public void decode(InputStream in, OutputStream out)
            throws AndrolibException {
        try {
            XmlPullWrapperFactory factory = XmlPullWrapperFactory.newInstance();
            XmlPullParserWrapper par = factory.newPullParserWrapper(mParser);
            final ResTable resTable = ((AXmlResourceParser)mParser).getAttrDecoder().getCurrentPackage().getResTable();
            final boolean optimizeForManifest = mOptimizeForManifest;
            XmlSerializerWrapper ser = new StaticXmlSerializerWrapper(mSerial, factory){
                boolean hideSdkInfo = false;
                @Override
                public void event(XmlPullParser pp) throws XmlPullParserException, IOException {
                    int type = pp.getEventType();
                    int newLine = pp.getLineNumber();
                    if ((!optimizeForManifest) || newLine != 0) {
                        ((ExtXmlSerializer)xs).setLineNumber(newLine, type);
                        super.event(pp);
                    } else {
                        if (type == XmlPullParser.START_TAG) {
                            if ("uses-sdk".equalsIgnoreCase(pp.getName())) {
                                
                                //TODO:  parse uses-sdk( and some others?)
                                /*
                                 *  (--version-code)
                                 *  (--version-name)
                                 *  (debuggable)
                                 *  (...)
                                 *  --min-sdk-version
                                 *  --target-sdk-version
                                 *  --max-sdk-version
                                 */
                                try {
                                    hideSdkInfo = parseAttr(pp);
                                    if(hideSdkInfo) {
                                        return;
                                    }
                                } catch (AndrolibException e) {}
                            }
                            LOGGER.warning("Found generated line but parse failed, output it in xml.");
                        } else if (hideSdkInfo && type == XmlPullParser.END_TAG && 
                                "uses-sdk".equalsIgnoreCase(pp.getName())) {
                            return;
                        }
                        //((ExtXmlSerializer)xs).setLineNumber(newLine, type);
                        super.event(pp);
                    }
                }
                
                private boolean parseAttr(XmlPullParser pp) throws AndrolibException {
                    ResTable restable = resTable;
                    for (int i = 0; i < pp.getAttributeCount(); i++) {
                        final String a_ns = "http://schemas.android.com/apk/res/android";
                        String ns = pp.getAttributeNamespace (i);
                        if (a_ns.equalsIgnoreCase(ns)) {
                            String name = pp.getAttributeName (i);
                            String value = pp.getAttributeValue (i);
                            if (name != null && value != null) {
                                if (name.equalsIgnoreCase("minSdkVersion") || 
                                        name.equalsIgnoreCase("targetSdkVersion") || 
                                        name.equalsIgnoreCase("maxSdkVersion")) {
                                    restable.addSdkInfo(name, value);
                                } else {
                                    restable.clearSdkInfo();
                                    return false;//Found unknown flags
                                }
                            }
                        } else {
                            resTable.clearSdkInfo();
                            return false;//Found unknown flags
                        }
                    }
                    return true;
                }
            };
	//factory.newSerializerWrapper(mSerial);

            par.setInput(in, null);
            ser.setOutput(out, null);

            while (par.nextToken() != XmlPullParser.END_DOCUMENT) {
                ser.event(par);
            }
            mSerial.newLine();
            ser.flush();
        } catch (XmlPullParserException ex) {
            throw new AndrolibException("Could not decode XML", ex);
        } catch (IOException ex) {
            throw new AndrolibException("Could not decode XML", ex);
        }
    }

    public void decodeManifest(InputStream in, OutputStream out)
            throws AndrolibException {
        mOptimizeForManifest = true;
        try {
            decode(in, out);
        } finally {
            mOptimizeForManifest = false;
        }
    }

    private final XmlPullParser mParser;
    private final ExtXmlSerializer mSerial;

    private boolean mOptimizeForManifest = false;

    private final static Logger LOGGER =
        Logger.getLogger(XmlPullStreamDecoder.class.getName());
}

@@ -710,92 +710,8 @@
 on;%0A
-import brut.androlib.res.AndrolibResources;%0Aimport brut.androlib.res.data.ResTable;%0A
 impo
@@ -754,16 +754,16 @@
 alizer;%0A
+
 import j
@@ -867,74 +867,8 @@
 r.*;
-%0Aimport org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper;
 %0A%0A/*
@@ -1444,3725 +1444,35 @@
     
-final ResTable resTable = ((AXmlResourceParser)mParser).getAttrDecoder().getCurrentPackage().getResTable();%0A            final boolean optimizeForManifest = mOptimizeForManifest;%0A            XmlSerializerWrapper ser = new StaticXmlSerializerWrapper(mSerial, factory)%7B%0A                boolean hideSdkInfo = false;%0A                @Override%0A                public void event(XmlPullParser pp) throws XmlPullParserException, IOException %7B%0A                    int type = pp.getEventType();%0A                    int newLine = pp.getLineNumber();%0A                    if ((!optimizeForManifest) %7C%7C newLine != 0) %7B%0A                        ((ExtXmlSerializer)xs).setLineNumber(newLine, type);%0A                        super.event(pp);%0A                    %7D else %7B%0A                        if (type == XmlPullParser.START_TAG) %7B%0A                            if (%22uses-sdk%22.equalsIgnoreCase(pp.getName())) %7B%0A                                %0A                                //TODO:  parse uses-sdk( and some others?)%0A                                /*%0A                                 *  (--version-code)%0A                                 *  (--version-name)%0A                                 *  (debuggable)%0A                                 *  (...)%0A                                 *  --min-sdk-version%0A                                 *  --target-sdk-version%0A                                 *  --max-sdk-version%0A                                 */%0A                                try %7B%0A                                    hideSdkInfo = parseAttr(pp);%0A                                    if(hideSdkInfo) %7B%0A                                        return;%0A                                    %7D%0A                                %7D catch (AndrolibException e) %7B%7D%0A                            %7D%0A                            LOGGER.warning(%22Found generated line but parse failed, output it in xml.%22);%0A                        %7D else if (hideSdkInfo && type == XmlPullParser.END_TAG && %0A                                %22uses-sdk%22.equalsIgnoreCase(pp.getName())) %7B%0A                            return;%0A                        %7D%0A                        //((ExtXmlSerializer)xs).setLineNumber(newLine, type);%0A                        super.event(pp);%0A                    %7D%0A                %7D%0A                %0A                private boolean parseAttr(XmlPullParser pp) throws AndrolibException %7B%0A                    ResTable restable = resTable;%0A                    for (int i = 0; i %3C pp.getAttributeCount(); i++) %7B%0A                        final String a_ns = %22http://schemas.android.com/apk/res/android%22;%0A                        String ns = pp.getAttributeNamespace (i);%0A                        if (a_ns.equalsIgnoreCase(ns)) %7B%0A                            String name = pp.getAttributeName (i);%0A                            String value = pp.getAttributeValue (i);%0A                            if (name != null && value != null) %7B%0A                                if (name.equalsIgnoreCase(%22minSdkVersion%22) %7C%7C %0A                                        name.equalsIgnoreCase(%22targetSdkVersion%22) %7C%7C %0A                                        name.equalsIgnoreCase(%22maxSdkVersion%22)) %7B%0A                                    restable.addSdkInfo(name, value);%0A                                %7D else %7B%0A                                    restable.clearSdkInfo();%0A                                    return false;//Found unknown flags%0A                                %7D%0A                            %7D%0A                        %7D else %7B%0A                            resTable.clearSdkInfo();%0A                            return false;//Found unknown flags%0A                        %7D%0A                    %7D%0A                    return true;%0A                %7D%0A            %7D;%0A%09//
+XmlSerializerWrapper ser = 
 fact

fix callbacks to old methods