package org.codehaus.jackson.impl;

import org.codehaus.jackson.*;

/**
 * Extension of {@link JsonStreamContext}, which implements
 * core methods needed, and also exposes
 * more complete API to generator implementation classes.
 */
public abstract class JsonWriteContext
    extends JsonStreamContext
{
    // // // Return values for writeValue()

    public final static int STATUS_OK_AS_IS = 0;
    public final static int STATUS_OK_AFTER_COMMA = 1;
    public final static int STATUS_OK_AFTER_COLON = 2;
    public final static int STATUS_OK_AFTER_SPACE = 3; // in root context
    public final static int STATUS_EXPECT_VALUE = 4;
    public final static int STATUS_EXPECT_NAME = 5;

    protected final JsonWriteContext _parent;

    /*
    /**********************************************************
    /* Simple instance reuse slots; speed up things
    /* a bit (10-15%) for docs with lots of small
    /* arrays/objects
    /**********************************************************
     */

    protected JsonWriteContext _childArray = null;

    protected JsonWriteContext _childObject = null;

    /*
    /**********************************************************
    /* Life-cycle
    /**********************************************************
     */

    protected JsonWriteContext(int type, JsonWriteContext parent)
    {
        super(type);
        _parent = parent;
    }

    // // // Factory methods

    public static JsonWriteContext createRootContext()
    {
        return new RootWContext();
    }

    public final JsonWriteContext createChildArrayContext()
    {
        JsonWriteContext ctxt = _childArray;
        if (ctxt == null) {
            _childArray = ctxt = new ArrayWContext(this);
        } else { // need to reset settings; parent is already ok
            ctxt._index = -1;
        }
        return ctxt;
    }

    public final JsonWriteContext createChildObjectContext()
    {
        JsonWriteContext ctxt = _childObject;
        if (ctxt == null) {
            _childObject = ctxt = new ObjectWContext(this);
        } else { // need to reset settings; parent is already ok
            ctxt._index = -1;
        }
        return ctxt;
    }

    // // // Shared API

    public final JsonWriteContext getParent() { return _parent; }

    // // // API sub-classes are to implement

    /**
     * Method that writer is to call before it writes a field name.
     *
     * @return Index of the field entry (0-based)
     */
    public abstract int writeFieldName(String name);

    public abstract int writeValue();

    // // // Internally used abstract methods

    protected abstract void appendDesc(StringBuilder sb);

    // // // Overridden standard methods

    /**
     * Overridden to provide developer writeable "JsonPath" representation
     * of the context.
     */
    public final String toString()
    {
        StringBuilder sb = new StringBuilder(64);
        appendDesc(sb);
        return sb.toString();
    }
}

/**
 * Root context is simple, as only state it keeps is the index of
 * the currently active entry.
 */
final class RootWContext
    extends JsonWriteContext
{
    public RootWContext()
    {
        super(TYPE_ROOT, null);
    }

    public String getCurrentName() { return null; }

    public int writeFieldName(String name)
    {
        return STATUS_EXPECT_VALUE;
    }

    public int writeValue()
    {
        // No commas within root context, but need space
        ++_index;
        return (_index == 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_SPACE;
    }

    protected void appendDesc(StringBuilder sb)
    {
        sb.append("/");
    }
}

final class ArrayWContext
    extends JsonWriteContext
{
    public ArrayWContext(JsonWriteContext parent)
    {
        super(TYPE_ARRAY, parent);
    }

    public String getCurrentName() { return null; }

    public int writeFieldName(String name)
    {
        return STATUS_EXPECT_VALUE;
    }

    public int writeValue()
    {
        int ix = _index;
        ++_index;
        return (ix < 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_COMMA;
    }

    protected void appendDesc(StringBuilder sb)
    {
        sb.append('[');
        sb.append(getCurrentIndex());
        sb.append(']');
    }
}

final class ObjectWContext
    extends JsonWriteContext
{
    /**
     * Name of the field of which value is to be parsed.
     */
    protected String _currentName;

    /**
     * Flag to indicate that the context just received the
     * field name, and is to get a value next
     */
    protected boolean _expectValue;

    public ObjectWContext(JsonWriteContext parent)
    {
        super(TYPE_OBJECT, parent);
        _currentName = null;
        _expectValue = false;
    }

    public String getCurrentName() { return _currentName; }

    public int writeFieldName(String name)
    {
        if (_currentName != null) { // just wrote a name...
            return STATUS_EXPECT_VALUE;
        }
        _currentName = name;
        return (_index < 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_COMMA;
    }

    public int writeValue()
    {
        if (_currentName == null) {
            return STATUS_EXPECT_NAME;
        }
        _currentName = null;
        ++_index;
        return STATUS_OK_AFTER_COLON;
    }

    protected void appendDesc(StringBuilder sb)
    {
        sb.append('{');
        if (_currentName != null) {
            sb.append('"');
            // !!! TODO: Name chars should be escaped?
            sb.append(_currentName);
            sb.append('"');
        } else {
            sb.append('?');
        }
        sb.append(']');
    }
}
