//
// Copyright 2006 The Android Open Source Project
//
// Build resource files from raw assets.
//

#ifndef XML_NODE_H
#define XML_NODE_H

#include "StringPool.h"
#include "ResourceTable.h"

class XMLNode;

extern const char* const RESOURCES_ROOT_NAMESPACE;
extern const char* const RESOURCES_ANDROID_NAMESPACE;

bool isWhitespace(const char16_t* str);

String16 getNamespaceResourcePackage(String16 namespaceUri);

status_t parseStyledString(Bundle* bundle,
                           const char* fileName,
                           ResXMLTree* inXml,
                           const String16& endTag,
                           String16* outString,
                           Vector<StringPool::entry_style_span>* outSpans,
                           bool isPseudolocalizable);

void printXMLBlock(ResXMLTree* block);

status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,
                          bool stripAll=true, bool keepComments=false,
                          const char** cDataTags=NULL);

class XMLNode : public RefBase
{
public:
    static sp<XMLNode> parse(const sp<AaptFile>& file);

    static inline
    sp<XMLNode> newNamespace(const String8& filename, const String16& prefix, const String16& uri) {
        return new XMLNode(filename, prefix, uri, true);
    }
    
    static inline
    sp<XMLNode> newElement(const String8& filename, const String16& ns, const String16& name) {
        return new XMLNode(filename, ns, name, false);
    }
    
    static inline
    sp<XMLNode> newCData(const String8& filename) {
        return new XMLNode(filename);
    }
    
    enum type {
        TYPE_NAMESPACE,
        TYPE_ELEMENT,
        TYPE_CDATA
    };
    
    type getType() const;
    
    const String16& getNamespacePrefix() const;
    const String16& getNamespaceUri() const;
    
    const String16& getElementNamespace() const;
    const String16& getElementName() const;
    const Vector<sp<XMLNode> >& getChildren() const;

    struct attribute_entry {
        attribute_entry() : index(~(uint32_t)0), nameResId(0)
        {
            value.dataType = Res_value::TYPE_NULL;
        }

        bool needStringValue() const {
            return nameResId == 0
                || value.dataType == Res_value::TYPE_NULL
                || value.dataType == Res_value::TYPE_STRING;
        }
        
        String16 ns;
        String16 name;
        String16 string;
        Res_value value;
        uint32_t index;
        uint32_t nameResId;
        mutable uint32_t namePoolIdx;
    };

    const Vector<attribute_entry>& getAttributes() const;

    const String16& getCData() const;

    const String16& getComment() const;

    int32_t getStartLineNumber() const;
    int32_t getEndLineNumber() const;

    status_t addChild(const sp<XMLNode>& child);

    status_t addAttribute(const String16& ns, const String16& name,
                          const String16& value);

    void setAttributeResID(size_t attrIdx, uint32_t resId);

    status_t appendChars(const String16& chars);

    status_t appendComment(const String16& comment);

    void setStartLineNumber(int32_t line);
    void setEndLineNumber(int32_t line);

    void removeWhitespace(bool stripAll=true, const char** cDataTags=NULL);

    status_t parseValues(const sp<AaptAssets>& assets, ResourceTable* table);

    status_t assignResourceIds(const sp<AaptAssets>& assets,
                               const ResourceTable* table = NULL);

    status_t flatten(const sp<AaptFile>& dest, bool stripComments,
            bool stripRawValues) const;

    void print(int indent=0);

private:
    struct ParseState
    {
        String8 filename;
        XML_Parser parser;
        sp<XMLNode> root;
        Vector<sp<XMLNode> > stack;
        String16 pendingComment;
    };

    static void XMLCALL
    startNamespace(void *userData, const char *prefix, const char *uri);
    static void XMLCALL
    startElement(void *userData, const char *name, const char **atts);
    static void XMLCALL
    characterData(void *userData, const XML_Char *s, int len);
    static void XMLCALL
    endElement(void *userData, const char *name);
    static void XMLCALL
    endNamespace(void *userData, const char *prefix);
    
    static void XMLCALL
    commentData(void *userData, const char *comment);
    
    // Creating an element node.
    XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace);
    
    // Creating a CDATA node.
    XMLNode(const String8& filename);
    
    status_t collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,
            bool stripComments, bool stripRawValues) const;

    status_t collect_attr_strings(StringPool* outPool,
        Vector<uint32_t>* outResIds, bool allAttrs) const;
        
    status_t collect_resid_strings(StringPool* outPool,
            Vector<uint32_t>* outResIds) const;

    status_t flatten_node(const StringPool& strings, const sp<AaptFile>& dest,
            bool stripComments, bool stripRawValues) const;

    String16 mNamespacePrefix;
    String16 mNamespaceUri;
    String16 mElementName;
    Vector<sp<XMLNode> > mChildren;
    Vector<attribute_entry> mAttributes;
    KeyedVector<uint32_t, uint32_t> mAttributeOrder;
    uint32_t mNextAttributeIndex;
    String16 mChars;
    Res_value mCharsValue;
    String16 mComment;
    String8 mFilename;
    int32_t mStartLineNumber;
    int32_t mEndLineNumber;
};

#endif
