/*
 * Copyright 2010 Google Inc.
 * 
 * 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.google.web.bindery.autobean.shared;

import com.google.web.bindery.autobean.shared.impl.StringQuoter;

import java.util.List;

/**
 * This interface provides an abstraction around the underlying data model
 * (JavaScriptObject, or JSON) used to encode an AutoBeanCodex payload.
 */
public interface Splittable {
  /**
   * A value that represents {@code null}.
   */
  Splittable NULL = StringQuoter.nullValue();

  /**
   * Returns a boolean representation of the data.
   */
  boolean asBoolean();

  /**
   * Returns a numeric representation of the data.
   */
  double asNumber();

  /**
   * Assign the splittable to the specified index of the {@code parent} object.
   */
  void assign(Splittable parent, int index);

  /**
   * Assign the splittable to the named property of the {@code parent} object.
   */
  void assign(Splittable parent, String propertyName);

  /**
   * Returns a string representation of the data.
   */
  String asString();

  /**
   * Clones the Splittable, ignoring cycles and tags.
   */
  Splittable deepCopy();

  /**
   * Returns the nth element of a list.
   */
  Splittable get(int index);

  /**
   * Returns the named property.
   */
  Splittable get(String key);

  /**
   * Returns a wire-format representation of the data.
   */
  String getPayload();

  /**
   * Returns all keys available in the Splittable. This method may be expensive
   * to compute.
   */
  List<String> getPropertyKeys();

  /**
   * Returns a value previously set with {@link #setReified(String, Object)}.
   */
  Object getReified(String key);

  /**
   * Returns {@code true} if the value of the Splittable is a boolean.
   */
  boolean isBoolean();

  /**
   * Returns {@code} true if {@link #size()} and {@link #get(int)} can be
   * expected to return meaningful values.
   */
  boolean isIndexed();

  /**
   * Returns {@code} true if {@link #getPropertyKeys()} and {@link #get(String)}
   * can be expected to return meaningful values.
   */
  boolean isKeyed();

  /**
   * Indicates if the nth element of a list is null or undefined.
   */
  boolean isNull(int index);

  /**
   * Indicates if the named property is null or undefined.
   */
  boolean isNull(String key);

  /**
   * Returns {@code true} if the value of the Splittable is numeric.
   */
  boolean isNumber();

  /**
   * Returns {@code true} if {@link #setReified(String, Object)} has been called
   * with the given key.
   */
  boolean isReified(String key);

  /**
   * Returns {@code} true if {@link #asString()} can be expected to return a
   * meaningful value.
   */
  boolean isString();

  /**
   * Returns {@code true} if the value of the key is undefined.
   */
  boolean isUndefined(String key);

  /**
   * Removes a tag value from the Splittable.
   *
   * @param key the key for the value to be removed
   */
  void removeReified(String key);

  /**
   * Associates a tag value with the Splittable.
   */
  void setReified(String key, Object object);

  /**
   * Resets the length of an indexed Splittable.
   */
  void setSize(int i);

  /**
   * Returns the size of an indexed Splittable.
   */
  int size();
}
