/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/**
 * This file defines the <code>PPB_IMEInputEvent_Dev</code> interface.
 */

label Chrome {
  M16 = 0.1,
  M21 = 0.2
};

[macro="PPB_IME_INPUT_EVENT_DEV_INTERFACE"]
interface PPB_IMEInputEvent_Dev {
  /**
   * Create() creates an IME input event with the given parameters. Normally
   * you will get an IME event passed through the <code>HandleInputEvent</code>
   * and will not need to create them, but some applications may want to create
   * their own for internal use.
   *
   * @param[in] instance The instance for which this event occurred.
   *
   * @param[in] type A <code>PP_InputEvent_Type</code> identifying the type of
   * input event. The type must be one of the IME event types.
   *
   * @param[in] time_stamp A <code>PP_TimeTicks</code> indicating the time
   * when the event occurred.
   *
   * @param[in] text The string returned by <code>GetText</code>.
   *
   * @param[in] segment_number The number returned by
   * <code>GetSegmentNumber</code>.
   *
   * @param[in] segment_offsets The array of numbers returned by
   * <code>GetSegmentOffset</code>. If <code>segment_number</code> is zero,
   * the number of elements of the array should be zero. If
   * <code>segment_number</code> is non-zero, the length of the array must be
   * <code>segment_number</code> + 1.
   *
   * @param[in] target_segment The number returned by
   * <code>GetTargetSegment</code>.
   *
   * @param[in] selection_start The start index returned by
   * <code>GetSelection</code>.
   *
   * @param[in] selection_end The end index returned by
   * <code>GetSelection</code>.
   *
   * @return A <code>PP_Resource</code> containing the new IME input event.
   */
  [version=0.2]
  PP_Resource Create([in] PP_Instance instance,
                     [in] PP_InputEvent_Type type,
                     [in] PP_TimeTicks time_stamp,
                     [in] PP_Var text,
                     [in] uint32_t segment_number,
                     [in] uint32_t[] segment_offsets,
                     [in] int32_t target_segment,
                     [in] uint32_t selection_start,
                     [in] uint32_t selection_end);

  /**
   * IsIMEInputEvent() determines if a resource is an IME event.
   *
   * @param[in] resource A <code>PP_Resource</code> corresponding to an event.
   *
   * @return <code>PP_TRUE</code> if the given resource is a valid input event.
   */
  PP_Bool IsIMEInputEvent([in] PP_Resource resource);

  /**
   * GetText() returns the composition text as a UTF-8 string for the given IME
   * event.
   *
   * @param[in] ime_event A <code>PP_Resource</code> corresponding to an IME
   * event.
   *
   * @return A string var representing the composition text. For non-IME input
   * events the return value will be an undefined var.
   */
  PP_Var GetText([in] PP_Resource ime_event);

  /**
   * GetSegmentNumber() returns the number of segments in the composition text.
   *
   * @param[in] ime_event A <code>PP_Resource</code> corresponding to an IME
   * event.
   *
   * @return The number of segments. For events other than COMPOSITION_UPDATE,
   * returns 0.
   */
  uint32_t GetSegmentNumber([in] PP_Resource ime_event);

  /**
   * GetSegmentOffset() returns the position of the index-th segmentation point
   * in the composition text. The position is given by a byte-offset (not a
   * character-offset) of the string returned by GetText(). It always satisfies
   * 0=GetSegmentOffset(0) < ... < GetSegmentOffset(i) < GetSegmentOffset(i+1)
   * < ... < GetSegmentOffset(GetSegmentNumber())=(byte-length of GetText()).
   * Note that [GetSegmentOffset(i), GetSegmentOffset(i+1)) represents the range
   * of the i-th segment, and hence GetSegmentNumber() can be a valid argument
   * to this function instead of an off-by-1 error.
   *
   * @param[in] ime_event A <code>PP_Resource</code> corresponding to an IME
   * event.
   *
   * @param[in] index An integer indicating a segment.
   *
   * @return The byte-offset of the segmentation point. If the event is not
   * COMPOSITION_UPDATE or index is out of range, returns 0.
   */
  uint32_t GetSegmentOffset([in] PP_Resource ime_event,
                            [in] uint32_t index);

  /**
   * GetTargetSegment() returns the index of the current target segment of
   * composition.
   *
   * @param[in] ime_event A <code>PP_Resource</code> corresponding to an IME
   * event.
   *
   * @return An integer indicating the index of the target segment. When there
   * is no active target segment, or the event is not COMPOSITION_UPDATE,
   * returns -1.
   */
  int32_t GetTargetSegment([in] PP_Resource ime_event);

  /**
   * GetSelection() returns the range selected by caret in the composition text.
   *
   * @param[in] ime_event A <code>PP_Resource</code> corresponding to an IME
   * event.
   *
   * @param[out] start The start position of the current selection.
   *
   * @param[out] end The end position of the current selection.
   */
  void GetSelection([in] PP_Resource ime_event,
                    [out] uint32_t start,
                    [out] uint32_t end);
};
