/*
 *  Copyright 2010 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.
 *  under the License.
 */

package brut.androlib.res.decoder;

import brut.androlib.*;
import brut.androlib.res.AndrolibResources;
import brut.androlib.res.data.ResPackage;
import brut.androlib.res.data.value.ResAttr;
import brut.androlib.res.data.value.ResScalarValue;
import brut.androlib.res.data.value.ResValue;
import java.io.IOException;
import org.xmlpull.mxp1_serializer.MXSerializer;
import org.xmlpull.v1.XmlSerializer;

/**
 * @author Ryszard Wiśniewski <brut.alll@gmail.com>
 */
public class ResXmlSerializer extends MXSerializer {
    private final static String RES_NAMESPACE =
        "http://schemas.android.com/apk/res/android";

    private ResPackage mCurrentPackage;
    private boolean mDecodingEnabled = true;

    @Override
    public XmlSerializer attribute(String namespace, String name, String value)
            throws IOException, IllegalArgumentException, IllegalStateException
            {
        if (! mDecodingEnabled) {
            return super.attribute(namespace, name, value);
        }
        
        try {
            ResScalarValue resValue =
                mCurrentPackage.getValueFactory().factory(value);

            if (namespace == null || namespace.isEmpty()) {
                value = resValue.toResXmlFormat();
            } else {
                String pkgName = RES_NAMESPACE.equals(namespace) ?
                    "android" : mCurrentPackage.getName();
                ResAttr attr = (ResAttr) mCurrentPackage.getResTable()
                    .getValue(pkgName, "attr", name);
                value = attr.convertToResXmlFormat(resValue);
            }
        } catch (AndrolibException ex) {
            throw new IllegalArgumentException(String.format(
                "could not decode attribute: ns=%s, name=%s, value=%s",
                namespace, name, value), ex);
        }

        if (value == null) {
            return this;
        }

//        if ("id".equals(name) && value.startsWith("@id")) {
        if (value.startsWith("@id")) {
            value = "@+id" + value.substring(3);
        }
        return super.attribute(namespace, name, value);
    }

    @Override
    public XmlSerializer text(String text) throws IOException {
        if (mDecodingEnabled) {
            text = AndrolibResources.escapeForResXml(text);
        }
        return super.text(text);
    }

    @Override
    public XmlSerializer text(char[] buf, int start, int len) throws IOException {
        if (mDecodingEnabled) {
            return this.text(new String(buf, start, len));
        }
        return super.text(buf, start, len);
    }

    @Override
    public void startDocument(String encoding, Boolean standalone) throws
            IOException, IllegalArgumentException, IllegalStateException {
        super.startDocument(encoding != null ? encoding : "UTF-8", standalone);
        super.out.write("\n");
        super.setPrefix("android", RES_NAMESPACE);
    }

    public void setCurrentPackage(ResPackage package_) {
        mCurrentPackage = package_;
    }

    public boolean setDecodingEnabled(boolean escapeRefs) {
        boolean oldVal = mDecodingEnabled;
        this.mDecodingEnabled = escapeRefs;
        return oldVal;
    }
}

@@ -2542,168 +2542,8 @@
  %7D%0A%0A
-//        if (%22id%22.equals(name) && value.startsWith(%22@id%22)) %7B%0A        if (value.startsWith(%22@id%22)) %7B%0A            value = %22@+id%22 + value.substring(3);%0A        %7D%0A
     

remove adding "+" to id references.