// Copyright 2010-2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package org.mozc.android.inputmethod.japanese.accessibility;

import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateWord;
import org.mozc.android.inputmethod.japanese.ui.CandidateLayout;
import org.mozc.android.inputmethod.japanese.ui.CandidateLayout.Row;
import org.mozc.android.inputmethod.japanese.ui.CandidateLayout.Span;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;

import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
import android.support.v4.view.accessibility.AccessibilityRecordCompat;
import android.util.SparseArray;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;

import javax.annotation.Nullable;

/**
 * Represents candidate window's virtual structure.
 *
 * <p>Note about virtual view ID: This class uses {@code CandidateWord}'s {@code id}
 * as virtual view ID.
 */
class CandidateWindowAccessibilityNodeProvider extends AccessibilityNodeProviderCompat {

  @VisibleForTesting static final int UNDEFINED = Integer.MIN_VALUE;
  @VisibleForTesting static final int FOLD_BUTTON_ID = Integer.MIN_VALUE + 1;
  private Optional<CandidateLayout> layout = Optional.absent();
  // The view backed by this class.
  private final View view;
  // Caches only Row. Caches Span might be slow on construction.
  private Optional<SparseArray<Row>> virtualViewIdToRow = Optional.absent();
  // Virtual ID of focused (in the light of accessibility) view.
  private int virtualFocusedViewId = UNDEFINED;

  CandidateWindowAccessibilityNodeProvider(View view) {
    this.view = Preconditions.checkNotNull(view);
  }

  private Context getContext() {
    return view.getContext();
  }

  /**
   * Sets updated layout and resets virtual view structure.
   */
  void setCandidateLayout(Optional<CandidateLayout> layout) {
    this.layout = Preconditions.checkNotNull(layout);
    resetVirtualStructure();
  }

  /**
   * Returns a {@code Row} which contains a {@code CandidateWord} of which the
   * {@code id} is given {@code virtualViewId}.
   */
  private Optional<Row> getRow(int virtualViewId) {
    if (!virtualViewIdToRow.isPresent()) {
      if (!layout.isPresent()) {
        return Optional.absent();
      }
      SparseArray<Row> virtualViewIdToRow = new SparseArray<Row>();
      for (Row row : layout.get().getRowList()) {
        for (Span span : row.getSpanList()) {
          if (span.getCandidateWord().isPresent()) {
            // - Skip reserved empty span, which is for folding button.
            // - Use append method expecting that the id is in ascending order.
            //   Even if not, it works well.
            virtualViewIdToRow.append(span.getCandidateWord().get().getId(), row);
          } else {
            virtualViewIdToRow.append(FOLD_BUTTON_ID, row);
          }
        }
      }
      this.virtualViewIdToRow = Optional.of(virtualViewIdToRow);
    }
    return Optional.fromNullable(virtualViewIdToRow.get().get(virtualViewId));
  }

  private Optional<AccessibilityNodeInfoCompat> createNodeInfoForId(int virtualViewId) {
    Optional<Row> optionalRow = getRow(virtualViewId);
    if (!optionalRow.isPresent()) {
      return Optional.absent();
    }
    Row row = optionalRow.get();
    for (Span span : row.getSpanList()) {
      if (span.getCandidateWord().isPresent()
          && span.getCandidateWord().get().getId() != virtualViewId) {
        continue;
      }
      AccessibilityNodeInfoCompat info = createNodeInfoForSpan(virtualViewId, row, span);
      info.setContentDescription(span.getCandidateWord().isPresent()
          ? getContentDescription(span.getCandidateWord().get()) : null);
      if (virtualFocusedViewId == virtualViewId) {
        info.addAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
      } else {
        info.addAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
      }
      return Optional.of(info);
    }
    return Optional.absent();
  }

  private AccessibilityNodeInfoCompat createNodeInfoForSpan(int virtualViewId, Row row, Span span) {
    AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
    Rect boundsInParent =
        new Rect((int) (span.getLeft()), (int) (row.getTop()),
                 (int) (span.getRight()), (int) (row.getTop() + row.getHeight()));
    int[] parentLocationOnScreen = new int[2];
    view.getLocationOnScreen(parentLocationOnScreen);
    Rect boundsInScreen = new Rect(boundsInParent);
    boundsInScreen.offset(parentLocationOnScreen[0], parentLocationOnScreen[1]);

    info.setPackageName(getContext().getPackageName());
    info.setClassName(Span.class.getName());
    info.setBoundsInParent(boundsInParent);
    info.setBoundsInScreen(boundsInScreen);
    info.setParent(view);
    info.setSource(view, virtualViewId);
    info.setEnabled(true);
    info.setVisibleToUser(true);
    return info;
  }

  @Nullable
  @Override
  public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) {
    if (virtualViewId == UNDEFINED) {
      return null;
    }
    if (virtualViewId == View.NO_ID) {
      // Required to return the information about entire view.
      AccessibilityNodeInfoCompat info =
          AccessibilityNodeInfoCompat.obtain(view);
      Preconditions.checkNotNull(info);
      ViewCompat.onInitializeAccessibilityNodeInfo(view, info);
      if (!layout.isPresent()) {
        return info;
      }
      for (Row row : layout.get().getRowList()) {
        for (Span span : row.getSpanList()) {
          if (span.getCandidateWord().isPresent()) {
            // Skip reserved empty span, which is for folding button.
            info.addChild(view, span.getCandidateWord().get().getId());
          } else {
            info.addChild(view, FOLD_BUTTON_ID);
          }
        }
      }
      return info;
    }
    return createNodeInfoForId(virtualViewId).orNull();
  }

  private boolean isAccessibilityEnabled() {
    return AccessibilityUtil.isAccessibilityEnabled(getContext());
  }

  private void resetVirtualStructure() {
    virtualViewIdToRow = Optional.absent();
    if (isAccessibilityEnabled()) {
      AccessibilityEvent event = AccessibilityEvent.obtain();
      ViewCompat.onInitializeAccessibilityEvent(view, event);
      event.setEventType(AccessibilityEventCompat.TYPE_WINDOW_CONTENT_CHANGED);
      AccessibilityUtil.sendAccessibilityEvent(getContext(), event);
    }
  }

  /**
   * Returns a {@code CandidateWord} based on given position if available.
   *
   * @param x horizontal location in screen coordinate (pixel)
   * @param y vertical location in screen coordinate (pixel)
   */
  Optional<CandidateWord> getCandidateWord(int x, int y) {
    for (Row row : layout.get().getRowList()) {
      if (y < row.getTop() || y >= row.getTop() + row.getHeight()) {
        continue;
      }
      for (Span span : row.getSpanList()) {
        if (x >= span.getLeft() && x < span.getRight()) {
          return span.getCandidateWord();
        }
      }
    }
    return Optional.absent();
  }

  void sendAccessibilityEventForCandidateWordIfAccessibilityEnabled(CandidateWord candidateWord,
                                                                    int eventType) {
    if (isAccessibilityEnabled()) {
      AccessibilityEvent event = createAccessibilityEvent(candidateWord, eventType);
      AccessibilityUtil.sendAccessibilityEvent(getContext(), event);
    }
  }

  private AccessibilityEvent createAccessibilityEvent(CandidateWord candidateWord,
                                                      int eventType) {
    Preconditions.checkNotNull(candidateWord);

    AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
    event.setPackageName(getContext().getPackageName());
    event.setClassName(candidateWord.getClass().getName());
    event.setContentDescription(getContentDescription(candidateWord));
    event.setEnabled(true);
    AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
    record.setSource(view, candidateWord.getId());
    return event;
  }

  /**
   * Returns content description based on value and annotation.
   */
  private String getContentDescription(CandidateWord candidateWord) {
    Preconditions.checkNotNull(candidateWord);
    String contentDescription = Strings.nullToEmpty(candidateWord.getValue());
    if (candidateWord.hasAnnotation() && candidateWord.getAnnotation().hasDescription()) {
      contentDescription += " " + candidateWord.getAnnotation().getDescription();
    }
    return contentDescription;
  }

  private Optional<CandidateWord> getCandidateWordFromId(int id) {
    Optional<Row> optionalRow = getRow(id);
    if (!optionalRow.isPresent()) {
      return Optional.absent();
    }
    Row row = optionalRow.get();
    for (Span span : row.getSpanList()) {
      Optional<CandidateWord> candidateWord = span.getCandidateWord();
      if (candidateWord.isPresent() && candidateWord.get().getId() == id) {
        return candidateWord;
      }
    }
    return Optional.absent();
  }

  @Override
  public boolean performAction(int virtualViewId, int action, Bundle arguments) {
    Optional<CandidateWord> candidateWord = getCandidateWordFromId(virtualViewId);
    return candidateWord.isPresent()
        ? performActionForCandidateWordInternal(candidateWord.get(), virtualViewId, action)
        : false;
  }

  boolean performActionForCandidateWord(CandidateWord candidateWord,
                                        int actionAccessibilityFocus) {
    Preconditions.checkNotNull(candidateWord);
    return performActionForCandidateWordInternal(candidateWord, candidateWord.getId(),
                                                 actionAccessibilityFocus);
  }

  private boolean performActionForCandidateWordInternal(CandidateWord candidateWord,
                                                        int virtualViewId, int action) {
    Preconditions.checkNotNull(candidateWord);

    switch (action) {
      case AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS:
        if (virtualFocusedViewId == virtualViewId) {
          // If focused virtual view is unchanged, do nothing.
          return false;
        }
        // Framework requires the candidate window to have focus.
        // Return FOCUSED event to the framework as response.
        virtualFocusedViewId = virtualViewId;
        if (isAccessibilityEnabled()) {
          AccessibilityUtil.sendAccessibilityEvent(
              getContext(),
              createAccessibilityEvent(
                  candidateWord,
                  AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED));
        }
        return true;
      case AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
        // Framework requires the candidate window to clear focus.
        // Return FOCUSE_CLEARED event to the framework as response.
        if (virtualFocusedViewId != virtualViewId) {
          return false;
        }
        virtualFocusedViewId = UNDEFINED;
        if (isAccessibilityEnabled()) {
          AccessibilityUtil.sendAccessibilityEvent(
              getContext(),
              createAccessibilityEvent(
                  candidateWord,
                  AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED));
        }
        return true;
      default:
        return false;
    }
  }
}