/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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 com.android.gallery3d.picasa;

import android.text.format.Time;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

public final class GDataParser implements ContentHandler {
    public static final String APP_NAMESPACE = "http://www.w3.org/2007/app";
    public static final String ATOM_NAMESPACE = "http://www.w3.org/2005/Atom";
    public static final String GD_NAMESPACE = "http://schemas.google.com/g/2005";
    public static final String GPHOTO_NAMESPACE = "http://schemas.google.com/photos/2007";
    public static final String MEDIA_RSS_NAMESPACE = "http://search.yahoo.com/mrss/";
    public static final String GML_NAMESPACE = "http://www.opengis.net/gml";
    private static final String FEED_ELEMENT = "feed";
    private static final String ENTRY_ELEMENT = "entry";

    private static final int STATE_DOCUMENT = 0;
    private static final int STATE_FEED = 1;
    private static final int STATE_ENTRY = 2;

    private static final int NUM_LEVELS = 5;

    private Entry mEntry = null;
    private EntryHandler mHandler = null;
    private int mState = STATE_DOCUMENT;
    private int mLevel = 0;
    private final String[] mUri = new String[NUM_LEVELS];
    private final String[] mName = new String[NUM_LEVELS];
    private final AttributesImpl[] mAttributes = new AttributesImpl[NUM_LEVELS];
    private final StringBuilder mValue = new StringBuilder(128);

    public interface EntryHandler {
        void handleEntry(Entry entry);
    }

    public GDataParser() {
        AttributesImpl[] attributes = mAttributes;
        for (int i = 0; i != NUM_LEVELS; ++i) {
            attributes[i] = new AttributesImpl();
        }
    }

    public void setEntry(Entry entry) {
        mEntry = entry;
    }

    public void setHandler(EntryHandler handler) {
        mHandler = handler;
    }

    public static long parseAtomTimestamp(String timestamp) {
        Time time = new Time();
        time.parse3339(timestamp);
        return time.toMillis(true);
    }

    public void startElement(String uri, String localName, String qName, Attributes attrs)
            throws SAXException {
        switch (mState) {
            case STATE_DOCUMENT:
                // Expect an atom:feed element.
                if (uri.equals(ATOM_NAMESPACE) && localName.equals(FEED_ELEMENT)) {
                    mState = STATE_FEED;
                } else {
                    throw new SAXException();
                }
                break;
            case STATE_FEED:
                // Expect a feed property element or an atom:entry element.
                if (uri.equals(ATOM_NAMESPACE) && localName.equals(ENTRY_ELEMENT)) {
                    mState = STATE_ENTRY;
                    mEntry.clear();
                } else {
                    startProperty(uri, localName, attrs);
                }
                break;
            case STATE_ENTRY:
                startProperty(uri, localName, attrs);
                break;
        }
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (mLevel > 0) {
            // Handle property exit.
            endProperty();
        } else {
            // Handle state exit.
            switch (mState) {
            case STATE_DOCUMENT:
                throw new SAXException();
            case STATE_FEED:
                mState = STATE_DOCUMENT;
                break;
            case STATE_ENTRY:
                mState = STATE_FEED;
                mHandler.handleEntry(mEntry);
                break;
            }
        }
    }

    private void startProperty(String uri, String localName, Attributes attrs) {
        // Push element information onto the property stack.
        int level = ++mLevel;
        mValue.setLength(0);
        mUri[level] = uri;
        mName[level] = localName;
        mAttributes[level].setAttributes(attrs);
    }

    private void endProperty() {
        // Apply property to the entry, then pop the stack.
        int level = mLevel;
        mEntry.setPropertyFromXml(mUri[level], mName[level], mAttributes[level], mValue.toString());
        mLevel = level - 1;
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        mValue.append(ch, start, length);
    }

    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
        // Ignored.
    }

    public void processingInstruction(String target, String data) throws SAXException {
        // Ignored.
    }

    public void setDocumentLocator(Locator locator) {
        // Ignored.
    }

    public void skippedEntity(String name) throws SAXException {
        // Ignored.
    }

    public void startDocument() throws SAXException {
        // Ignored.
    }

    public void endDocument() throws SAXException {
        // Ignored.
    }

    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        // Ignored.
    }

    public void endPrefixMapping(String prefix) throws SAXException {
        // Ignored.
    }
}
