// 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;

import org.mozc.android.inputmethod.japanese.FeedbackManager.FeedbackEvent;
import org.mozc.android.inputmethod.japanese.emoji.EmojiProviderType;
import org.mozc.android.inputmethod.japanese.keyboard.BackgroundDrawableFactory;
import org.mozc.android.inputmethod.japanese.keyboard.BackgroundDrawableFactory.DrawableType;
import org.mozc.android.inputmethod.japanese.keyboard.KeyEventHandler;
import org.mozc.android.inputmethod.japanese.model.SymbolCandidateStorage;
import org.mozc.android.inputmethod.japanese.model.SymbolMajorCategory;
import org.mozc.android.inputmethod.japanese.model.SymbolMinorCategory;
import org.mozc.android.inputmethod.japanese.preference.PreferenceUtil;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateList;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateWord;
import org.mozc.android.inputmethod.japanese.resources.R;
import org.mozc.android.inputmethod.japanese.ui.CandidateLayoutRenderer.DescriptionLayoutPolicy;
import org.mozc.android.inputmethod.japanese.ui.CandidateLayoutRenderer.ValueScalingPolicy;
import org.mozc.android.inputmethod.japanese.ui.ScrollGuideView;
import org.mozc.android.inputmethod.japanese.ui.SpanFactory;
import org.mozc.android.inputmethod.japanese.ui.SymbolCandidateLayouter;
import org.mozc.android.inputmethod.japanese.view.MozcDrawableFactory;
import org.mozc.android.inputmethod.japanese.view.RoundRectKeyDrawable;
import org.mozc.android.inputmethod.japanese.view.SkinType;
import org.mozc.android.inputmethod.japanese.view.SymbolMajorCategoryButtonDrawableFactory;
import org.mozc.android.inputmethod.japanese.view.TabSelectedBackgroundDrawable;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Gravity;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabSpec;
import android.widget.TabWidget;
import android.widget.TextView;

import java.util.List;

/**
 * This class is used to show symbol input view on which an user can
 * input emoticon/symbol/emoji.
 *
 * In this class,
 * "Emoticon" means "Kaomoji", like ＼(^o^)／
 * "Symbol" means symbol character, like $ % ! €
 * "Emoji" means a more graphical character of face, building, food etc.
 *
 * This class treats all Emoticon, Symbol and Emoji category as "SymbolMajorCategory".
 * A major category has several minor categories.
 * Each minor category belongs to only one major category.
 * Major-Minor relation is defined by using R.layout.symbol_minor_category_*.
 *
 */
public class SymbolInputView extends InOutAnimatedFrameLayout implements MemoryManageable {

  /**
   * Adapter for symbol candidate selection.
   * Exposed as package private for testing.
   */
  // TODO(hidehiko): make this class static.
  class SymbolCandidateSelectListener implements CandidateSelectListener {
    @Override
    public void onCandidateSelected(CandidateWord candidateWord, Optional<Integer> row) {
      if (viewEventListener != null) {
        // If we are on password field, history shouldn't be updated to protect privacy.
        viewEventListener.onSymbolCandidateSelected(
            currentMajorCategory, candidateWord.getValue(), !isPasswordField);
      }
    }
  }

  /**
   * Click handler of major category buttons.
   */
  class MajorCategoryButtonClickListener implements OnClickListener {
    private final SymbolMajorCategory majorCategory;

    MajorCategoryButtonClickListener(SymbolMajorCategory majorCategory) {
      if (majorCategory == null) {
        throw new NullPointerException("majorCategory should not be null.");
      }
      this.majorCategory = majorCategory;
    }

    @Override
    public void onClick(View majorCategorySelectorButton) {
      if (viewEventListener != null) {
        viewEventListener.onFireFeedbackEvent(FeedbackEvent.INPUTVIEW_EXPAND);
      }

      if (emojiEnabled
          && majorCategory == SymbolMajorCategory.EMOJI
          && emojiProviderType == EmojiProviderType.NONE) {
        // Ask the user which emoji provider s/he'd like to use.
        // If the user cancels the dialog, do nothing.
        maybeInitializeEmojiProviderDialog(getContext());
        if (emojiProviderDialog != null) {
          IBinder token = getWindowToken();
          if (token != null) {
            MozcUtil.setWindowToken(token, emojiProviderDialog);
          } else {
            MozcLog.w("Unknown window token.");
          }

          // If a user selects a provider, the dialog handler will set major category
          // to EMOJI automatically. If s/he cancels, nothing will be happened.
          emojiProviderDialog.show();
          return;
        }
      }

      setMajorCategory(majorCategory);
    }
  }

  // Manages the relationship between.
  static class SymbolTabWidgetViewPagerAdapter extends PagerAdapter
      implements OnTabChangeListener, OnPageChangeListener {

    private static final int HISTORY_INDEX = 0;

    private final Context context;
    private final SymbolCandidateStorage symbolCandidateStorage;
    private final ViewEventListener viewEventListener;
    private final CandidateSelectListener candidateSelectListener;
    private final SymbolMajorCategory majorCategory;
    private final SkinType skinType;
    private final EmojiProviderType emojiProviderType;
    private final TabHost tabHost;
    private final ViewPager viewPager;
    private final float candidateTextSize;
    private final float descriptionTextSize;

    private View historyViewCache = null;
    private int scrollState = ViewPager.SCROLL_STATE_IDLE;

    SymbolTabWidgetViewPagerAdapter(
        Context context, SymbolCandidateStorage symbolCandidateStorage,
        ViewEventListener viewEventListener, CandidateSelectListener candidateSelectListener,
        SymbolMajorCategory majorCategory,
        SkinType skinType, EmojiProviderType emojiProviderType,
        TabHost tabHost, ViewPager viewPager,
        float candidateTextSize, float descriptionTextSize) {
      Preconditions.checkNotNull(emojiProviderType);

      this.context = context;
      this.symbolCandidateStorage = symbolCandidateStorage;
      this.viewEventListener = viewEventListener;
      this.candidateSelectListener = candidateSelectListener;
      this.majorCategory = majorCategory;
      this.skinType = skinType;
      this.emojiProviderType = emojiProviderType;
      this.tabHost = tabHost;
      this.viewPager = viewPager;
      this.candidateTextSize = candidateTextSize;
      this.descriptionTextSize = descriptionTextSize;
    }

    private void maybeResetHistoryView() {
      if (viewPager.getCurrentItem() != HISTORY_INDEX && historyViewCache != null) {
        resetHistoryView();
      }
    }

    private void resetHistoryView() {
      CandidateList candidateList =
          symbolCandidateStorage.getCandidateList(majorCategory.minorCategories.get(0));
      if (candidateList.getCandidatesCount() == 0) {
        historyViewCache.findViewById(R.id.symbol_input_no_history).setVisibility(View.VISIBLE);
      } else {
        historyViewCache.findViewById(R.id.symbol_input_no_history).setVisibility(View.GONE);
      }
      SymbolCandidateView.class.cast(
          historyViewCache.findViewById(R.id.symbol_input_candidate_view)).update(candidateList);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
      if (scrollState == ViewPager.SCROLL_STATE_IDLE) {
        maybeResetHistoryView();
      }
      scrollState = state;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
      // Do nothing.
    }

    @Override
    public void onPageSelected(int position) {
      tabHost.setOnTabChangedListener(null);
      tabHost.setCurrentTab(position);
      tabHost.setOnTabChangedListener(this);

      if (viewEventListener != null) {
        viewEventListener.onFireFeedbackEvent(FeedbackEvent.INPUTVIEW_EXPAND);
      }
    }

    @Override
    public void onTabChanged(String tabId) {
      int position = Integer.parseInt(tabId);

      if (position == HISTORY_INDEX) {
        maybeResetHistoryView();
      }
      viewPager.setCurrentItem(position, false);

      if (viewEventListener != null) {
        viewEventListener.onFireFeedbackEvent(FeedbackEvent.INPUTVIEW_EXPAND);
      }
    }

    @Override
    public int getCount() {
      return majorCategory.minorCategories.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object item) {
      return view == item;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
      LayoutInflater inflater = LayoutInflater.from(context);
      inflater = inflater.cloneInContext(context);

      View view = MozcUtil.inflateWithOutOfMemoryRetrial(
          View.class, inflater, R.layout.symbol_candidate_view, Optional.<ViewGroup>absent(),
          false);
      SymbolCandidateView symbolCandidateView =
          SymbolCandidateView.class.cast(view.findViewById(R.id.symbol_input_candidate_view));
      symbolCandidateView.setCandidateSelectListener(candidateSelectListener);
      symbolCandidateView.setMinColumnWidth(
          context.getResources().getDimension(majorCategory.minColumnWidthResourceId));
      symbolCandidateView.setSkinType(skinType);
      symbolCandidateView.setEmojiProviderType(emojiProviderType);
      symbolCandidateView.setCandidateTextDimension(candidateTextSize, descriptionTextSize);

      // Set candidate contents.
      if (position == HISTORY_INDEX) {
        historyViewCache = view;
        resetHistoryView();
      } else {
        symbolCandidateView.update(symbolCandidateStorage.getCandidateList(
            majorCategory.minorCategories.get(position)));
        symbolCandidateView.updateScrollPositionBasedOnFocusedIndex();
      }

      ScrollGuideView scrollGuideView =
          ScrollGuideView.class.cast(view.findViewById(R.id.symbol_input_scroll_guide_view));
      scrollGuideView.setSkinType(skinType);

      // Connect guide and candidate view.
      scrollGuideView.setScroller(symbolCandidateView.scroller);
      symbolCandidateView.setScrollIndicator(scrollGuideView);

      container.addView(view);
      return view;
    }

    @Override
    public void destroyItem(ViewGroup collection, int position, Object view) {
      if (position == HISTORY_INDEX) {
        historyViewCache = null;
      }
      collection.removeView(View.class.cast(view));
    }
  }

  /**
   * The text view for the minor category tab.
   * The most thing is as same as base TextView, but if the text is too long to fit in
   * the view, this view automatically scales the text horizontally. (If there is enough
   * space, doesn't widen.)
   */
  private static class TabTextView extends TextView {

    /** Cached Paint instance to measure the text. */
    private final Paint paint = new Paint();

    TabTextView(Context context) {
      super(context);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
      super.onLayout(changed, left, top, right, bottom);
      resetTextXSize();
    }

    private void resetTextXSize() {
      // Reset the paint instance.
      Paint paint = this.paint;
      paint.reset();
      paint.setAntiAlias(true);
      paint.setTextSize(getTextSize());
      paint.setTypeface(getTypeface());

      // Measure the width for each line.
      CharSequence text = getText().toString();
      float maxTextWidth = 0;
      int beginIndex = 0;
      for (int i = beginIndex; i < text.length(); ++i) {
        if (text.charAt(i) == '\n') {
          // Split the line.
          float textWidth = paint.measureText(text, beginIndex, i);
          if (textWidth > maxTextWidth) {
            maxTextWidth = textWidth;
          }
          // Exclude '\n'.
          beginIndex = i + 1;
        }
      }
      {
        // Last line.
        float textWidth = paint.measureText(text, beginIndex, text.length());
        if (textWidth > maxTextWidth) {
          maxTextWidth = textWidth;
        }
      }

      // Calculate scale factory. Note that 0.98f is the heuristic value,
      // in order to avoid wrapping lines by sub px calculations just in case.
      float scaleX = (getWidth() - getPaddingLeft() - getPaddingRight()) * 0.98f / maxTextWidth;

      // Cap the scaleX by 1f not to widen.
      setTextScaleX(Math.min(scaleX, 1f));
    }
  }

  /**
   * An event listener for the menu dialog window.
   */
  private class EmojiProviderDialogListener implements DialogInterface.OnClickListener {
    private final Context context;

    EmojiProviderDialogListener(Context context) {
      this.context = context;
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
      String value;
      TypedArray typedArray =
          context.getResources().obtainTypedArray(R.array.pref_emoji_provider_type_values);
      try {
        value = typedArray.getString(which);
      } finally {
        typedArray.recycle();
      }
      sharedPreferences.edit()
          .putString(PreferenceUtil.PREF_EMOJI_PROVIDER_TYPE, value)
          .commit();
      setMajorCategory(SymbolMajorCategory.EMOJI);
    }
  }

  /**
   * The candidate view for SymbolInputView.
   *
   * The differences from CandidateView.CandidateWordViewForConversion are
   * 1) this class scrolls horizontally 2) the layout algorithm is simpler.
   */
  static class SymbolCandidateView extends CandidateWordView {
    private static final String DESCRIPTION_DELIMITER = "\n";

    private View scrollGuideView = null;
    private GestureDetector gestureDetector = null;

    public SymbolCandidateView(Context context) {
      super(context, Orientation.VERTICAL);
    }

    public SymbolCandidateView(Context context, AttributeSet attributeSet) {
      super(context, attributeSet, Orientation.VERTICAL);
    }

    public SymbolCandidateView(Context context, AttributeSet attributeSet, int defaultStyle) {
      super(context, attributeSet, defaultStyle, Orientation.VERTICAL);
    }

    // Shared instance initializer.
    {
      setBackgroundDrawableType(DrawableType.SYMBOL_CANDIDATE_BACKGROUND);
      Resources resources = getResources();
      scroller.setDecayRate(
          resources.getInteger(R.integer.symbol_input_scroller_velocity_decay_rate) / 1000000f);
      scroller.setMinimumVelocity(
          resources.getInteger(R.integer.symbol_input_scroller_minimum_velocity));
      layouter = new SymbolCandidateLayouter();
    }

    void setCandidateTextDimension(float textSize, float descriptionTextSize) {
      Preconditions.checkArgument(textSize > 0);
      Preconditions.checkArgument(descriptionTextSize > 0);

      Resources resources = getResources();

      float valueHorizontalPadding =
          resources.getDimension(R.dimen.candidate_horizontal_padding_size);
      float descriptionHorizontalPadding =
          resources.getDimension(R.dimen.symbol_description_right_padding);
      float descriptionVerticalPadding =
          resources.getDimension(R.dimen.symbol_description_bottom_padding);

      candidateLayoutRenderer.setValueTextSize(textSize);
      candidateLayoutRenderer.setValueHorizontalPadding(valueHorizontalPadding);
      candidateLayoutRenderer.setValueScalingPolicy(ValueScalingPolicy.UNIFORM);
      candidateLayoutRenderer.setDescriptionTextSize(descriptionTextSize);
      candidateLayoutRenderer.setDescriptionHorizontalPadding(descriptionHorizontalPadding);
      candidateLayoutRenderer.setDescriptionVerticalPadding(descriptionVerticalPadding);
      candidateLayoutRenderer.setDescriptionLayoutPolicy(DescriptionLayoutPolicy.OVERLAY);

      SpanFactory spanFactory = new SpanFactory();
      spanFactory.setValueTextSize(textSize);
      spanFactory.setDescriptionTextSize(descriptionTextSize);
      spanFactory.setDescriptionDelimiter(DESCRIPTION_DELIMITER);

      SymbolCandidateLayouter layouter = SymbolCandidateLayouter.class.cast(this.layouter);
      layouter.setSpanFactory(spanFactory);
      layouter.setRowHeight(resources.getDimensionPixelSize(R.dimen.symbol_view_candidate_height));
    }

    @Override
    SymbolCandidateLayouter getCandidateLayouter() {
      return SymbolCandidateLayouter.class.cast(super.getCandidateLayouter());
    }

    void setMinColumnWidth(float minColumnWidth) {
      getCandidateLayouter().setMinColumnWidth(minColumnWidth);
      updateLayouter();
    }

    void setOnGestureListener(OnGestureListener gestureListener) {
      if (gestureListener == null) {
        gestureDetector = null;
      } else {
        gestureDetector = new GestureDetector(getContext(), gestureListener);
      }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
      if (gestureDetector != null && gestureDetector.onTouchEvent(event)) {
        return true;
      }
      return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      if (scrollGuideView != null) {
        scrollGuideView.invalidate();
      }
    }

    void setScrollIndicator(View scrollGuideView) {
      this.scrollGuideView = scrollGuideView;
    }
  }

  private class OutAnimationAdapter extends AnimationAdapter {
    @Override
    public void onAnimationEnd(Animation animation) {
      // Releases candidate resources. Also, on some devices, this cancels repeating invalidation
      // to support emoji related stuff.
      TabHost tabHost = getTabHost();
      tabHost.setOnTabChangedListener(null);
      ViewPager candidateViewPager = getCandidateViewPager();
      candidateViewPager.setAdapter(null);
      candidateViewPager.setOnPageChangeListener(null);
    }
  }

  /**
   * Name to represent this view for logging.
   */
  static final KeyboardSpecificationName SPEC_NAME =
      new KeyboardSpecificationName("SYMBOL_INPUT_VIEW", 0, 1, 0);
  // Source ID of the delete button for logging usage stats.
  private static final int DELETE_BUTTON_SOURCE_ID = 1;

  // TODO(hidehiko): move these parameters to skin instance.
  private static final float BUTTON_CORNOR_RADIUS = 3.5f;  // in dip.
  private static final float BUTTON_LEFT_OFFSET = 2.0f;
  private static final float BUTTON_TOP_OFFSET = 2.0f;
  private static final float BUTTON_RIGHT_OFFSET = 2.0f;
  private static final float BUTTON_BOTTOM_OFFSET = 2.0f;

  private static final int MAJOR_CATEGORY_TOP_COLOR = 0xFFF5F5F5;
  private static final int MAJOR_CATEGORY_BOTTOM_COLOR = 0xFFD2D2D2;
  private static final int MAJOR_CATEGORY_PRESSED_TOP_COLOR = 0xFFAAAAAA;
  private static final int MAJOR_CATEGORY_PRESSED_BOTTOM_COLOR = 0xFF828282;
  private static final int MAJOR_CATEGORY_SHADOW_COLOR = 0x57000000;

  // TODO(hidehiko): This parameter is not fixed yet. Needs to revisit again.
  private static final float SYMBOL_VIEW_MINOR_CATEGORY_TAB_SELECTED_HEIGHT = 6f;

  private static final int NUM_TABS = 6;

  private SymbolCandidateStorage symbolCandidateStorage;

  @VisibleForTesting SymbolMajorCategory currentMajorCategory;
  @VisibleForTesting boolean emojiEnabled;
  private boolean isPasswordField;
  @VisibleForTesting EmojiProviderType emojiProviderType = EmojiProviderType.NONE;

  @VisibleForTesting SharedPreferences sharedPreferences;
  @VisibleForTesting AlertDialog emojiProviderDialog;

  private ViewEventListener viewEventListener;
  private final KeyEventButtonTouchListener deleteKeyEventButtonTouchListener =
      createDeleteKeyEventButtonTouchListener(getResources());
  private OnClickListener closeButtonClickListener = null;
  private final SymbolCandidateSelectListener symbolCandidateSelectListener =
      new SymbolCandidateSelectListener();

  private SkinType skinType = SkinType.ORANGE_LIGHTGRAY;
  private final MozcDrawableFactory mozcDrawableFactory = new MozcDrawableFactory(getResources());
  private final SymbolMajorCategoryButtonDrawableFactory majorCategoryButtonDrawableFactory =
      new SymbolMajorCategoryButtonDrawableFactory(
          mozcDrawableFactory,
          MAJOR_CATEGORY_TOP_COLOR,
          MAJOR_CATEGORY_BOTTOM_COLOR,
          MAJOR_CATEGORY_PRESSED_TOP_COLOR,
          MAJOR_CATEGORY_PRESSED_BOTTOM_COLOR,
          MAJOR_CATEGORY_SHADOW_COLOR,
          BUTTON_CORNOR_RADIUS * getResources().getDisplayMetrics().density);
  // Candidate text size in dip.
  private float candidateTextSize;
  // Description text size in dip.
  private float desciptionTextSize;

  public SymbolInputView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public SymbolInputView(Context context) {
    super(context);
  }

  public SymbolInputView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  {
    setOutAnimationListener(new OutAnimationAdapter());
    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
  }

  private static KeyEventButtonTouchListener createDeleteKeyEventButtonTouchListener(
      Resources resources) {
    // Use 8 as default value of backspace key code (only for testing).
    // This code is introduced just for testing purpose due to AndroidMock's limitation.
    // When we move to EasyMock, we can remove this method.
    int ucharBackspace = resources == null ? 8 : resources.getInteger(R.integer.uchar_backspace);
    return new KeyEventButtonTouchListener(DELETE_BUTTON_SOURCE_ID, ucharBackspace);
  }


  boolean isInflated() {
    return getChildCount() > 0;
  }

  void inflateSelf() {
    if (isInflated()) {
      throw new IllegalStateException("The symbol input view is already inflated.");
    }

    // Hack: Because we wrap the real context to inject "retrying" for Drawable loading,
    // LayoutInflater.from(getContext()).getContext() may be different from getContext().
    // So, we clone the inflater here, too, with actual context.
    Context context = getContext();
    LayoutInflater inflater = LayoutInflater.from(context);
    inflater = inflater.cloneInContext(context);
    MozcUtil.inflateWithOutOfMemoryRetrial(
        SymbolInputView.class, inflater, R.layout.symbol_view, Optional.<ViewGroup>of(this), true);
    // Note: onFinishInflate won't be invoked on android ver 3.0 or later, while it is invoked
    // on android 2.3 or earlier. So, we define another (but similar) method and invoke it here
    // manually.
    onFinishInflateSelf();
  }

  /**
   * Initializes the instance. Called only once.
   * {@code onFinishInflate()} is *not* invoked for the inflation of &lt;merge&gt; element we use.
   * So, instead, we define another onFinishInflate method and invoke this manually.
   */
  protected void onFinishInflateSelf() {
    initializeMajorCategoryButtons();
    initializeMinorCategoryTab();
    initializeCloseButton();
    initializeDeleteButton();

    resetMajorCategoryBackground();
    resetTabBackground();
    enableEmoji(emojiEnabled);
    reset();
  }

  private void resetCandidateViewPager() {
    if (!isInflated()) {
      return;
    }

    ViewPager candidateViewPager = getCandidateViewPager();
    TabHost tabHost = getTabHost();

    SymbolTabWidgetViewPagerAdapter adapter = new SymbolTabWidgetViewPagerAdapter(
        getContext(),
        symbolCandidateStorage, viewEventListener, symbolCandidateSelectListener,
        currentMajorCategory, skinType, emojiProviderType, tabHost, candidateViewPager,
        candidateTextSize, desciptionTextSize);
    candidateViewPager.setAdapter(adapter);
    candidateViewPager.setOnPageChangeListener(adapter);
    tabHost.setOnTabChangedListener(adapter);
  }

  private void resetMajorCategoryBackground() {
    View view = findViewById(R.id.symbol_major_category);
    if (view != null) {
      if (skinType == null) {
        view.setBackgroundColor(Color.BLACK);
      } else {
        view.setBackgroundResource(skinType.windowBackgroundResourceId);
      }
    }
  }

  private void setMozcDrawable(ImageView imageView, int resourceId) {
    Optional<Drawable> drawable = mozcDrawableFactory.getDrawable(resourceId);
    if (drawable.isPresent()) {
      imageView.setImageDrawable(drawable.get());
    }
  }

  /**
   * Sets click event handlers to each major category button.
   * It is necessary that the inflation has been done before this method invocation.
   */
  @SuppressWarnings("deprecation")
  private void initializeMajorCategoryButtons() {
    for (SymbolMajorCategory majorCategory : SymbolMajorCategory.values()) {
      ImageView view = ImageView.class.cast(findViewById(majorCategory.buttonResourceId));
      if (view == null) {
        throw new IllegalStateException(
            "The view corresponding to " + majorCategory.name() + " is not found.");
      }
      view.setOnClickListener(new MajorCategoryButtonClickListener(majorCategory));
      setMozcDrawable(view, majorCategory.buttonImageResourceId);

      switch (majorCategory) {
        case SYMBOL:
          view.setBackgroundDrawable(
              majorCategoryButtonDrawableFactory.createLeftButtonDrawable());
          break;
        case EMOJI:
          view.setBackgroundDrawable(
              majorCategoryButtonDrawableFactory.createRightButtonDrawable(emojiEnabled));
          break;
        default:
          view.setBackgroundDrawable(
              majorCategoryButtonDrawableFactory.createCenterButtonDrawable());
          break;
      }
    }
  }

  private void initializeMinorCategoryTab() {
    TabHost tabhost = TabHost.class.cast(findViewById(android.R.id.tabhost));
    tabhost.setup();

    float textSize = getResources().getDimension(R.dimen.symbol_view_minor_category_text_size);
    int textColor = getResources().getColor(android.R.color.black);

    // Create NUM_TABS (= 6) tabs.
    // Note that we may want to change the number of tabs, however due to the limitation of
    // the current TabHost implementation, it is difficult. Fortunately, all major categories
    // have the same number of minor categories, so we use it as hard-coded value.
    for (int i = 0; i < NUM_TABS; ++i) {
      // The tab's id is the index of the tab.
      TabSpec tab = tabhost.newTabSpec(String.valueOf(i));
      TextView textView = new TabTextView(getContext());
      textView.setTypeface(Typeface.DEFAULT_BOLD);
      textView.setTextColor(textColor);
      textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
      textView.setGravity(Gravity.CENTER);
      tab.setIndicator(textView);
      // Set dummy view for the content. The actual content will be managed by ViewPager.
      tab.setContent(R.id.symbol_input_dummy);
      tabhost.addTab(tab);
    }

    // Hack: Set the current tab to the non-default (neither 0 nor 1) position,
    // so that the reset process will set the view's visibility appropriately.
    tabhost.setCurrentTab(2);
  }

  @SuppressWarnings("deprecation")
  private void resetTabBackground() {
    if (!isInflated()) {
      return;
    }

    float density = getResources().getDisplayMetrics().density;

    TabWidget tabWidget = TabWidget.class.cast(findViewById(android.R.id.tabs));
    for (int i = 0; i < tabWidget.getTabCount(); ++i) {
      View view = tabWidget.getChildTabViewAt(i);
      view.setBackgroundDrawable(createTabBackgroundDrawable(skinType, density));
    }
  }

  private static Drawable createTabBackgroundDrawable(SkinType skinType, float density) {
    return new LayerDrawable(new Drawable[] {
        BackgroundDrawableFactory.createSelectableDrawable(
            new TabSelectedBackgroundDrawable(
                (int) (SYMBOL_VIEW_MINOR_CATEGORY_TAB_SELECTED_HEIGHT * density),
                skinType.symbolMinorCategoryTabSelectedColor),
            null),
        BackgroundDrawableFactory.createPressableDrawable(
            new ColorDrawable(skinType.symbolMinorCategoryTabPressedColor), null),
    });
  }

  private void resetTabText() {
    if (!isInflated()) {
      return;
    }

    TabWidget tabWidget = TabWidget.class.cast(findViewById(android.R.id.tabs));
    List<SymbolMinorCategory> minorCategoryList = currentMajorCategory.minorCategories;
    for (int i = 0; i < tabWidget.getChildCount(); ++i) {
      TextView textView = TextView.class.cast(tabWidget.getChildTabViewAt(i));
      textView.setText(minorCategoryList.get(i).textResourceId);
    }
  }

  private static Drawable createButtonBackgroundDrawable(SkinType skinType, float density) {
    return BackgroundDrawableFactory.createPressableDrawable(
        new RoundRectKeyDrawable(
            (int) (BUTTON_LEFT_OFFSET * density),
            (int) (BUTTON_TOP_OFFSET * density),
            (int) (BUTTON_RIGHT_OFFSET * density),
            (int) (BUTTON_BOTTOM_OFFSET * density),
            (int) (BUTTON_CORNOR_RADIUS * density),
            skinType.symbolPressedFunctionKeyTopColor,
            skinType.symbolPressedFunctionKeyBottomColor,
            skinType.symbolPressedFunctionKeyHighlightColor,
            skinType.symbolPressedFunctionKeyShadowColor),
        new RoundRectKeyDrawable(
            (int) (BUTTON_LEFT_OFFSET * density),
            (int) (BUTTON_TOP_OFFSET * density),
            (int) (BUTTON_RIGHT_OFFSET * density),
            (int) (BUTTON_BOTTOM_OFFSET * density),
            (int) (BUTTON_CORNOR_RADIUS * density),
            skinType.symbolReleasedFunctionKeyTopColor,
            skinType.symbolReleasedFunctionKeyBottomColor,
            skinType.symbolReleasedFunctionKeyHighlightColor,
            skinType.symbolReleasedFunctionKeyShadowColor));
  }

  @SuppressWarnings("deprecation")
  private void initializeCloseButton() {
    ImageView closeButton = ImageView.class.cast(findViewById(R.id.symbol_view_close_button));
    if (closeButtonClickListener != null) {
      closeButton.setOnClickListener(closeButtonClickListener);
    }
    closeButton.setBackgroundDrawable(
        createButtonBackgroundDrawable(skinType, getResources().getDisplayMetrics().density));
    setMozcDrawable(closeButton, R.raw.symbol__function__close);
    closeButton.setPadding(2, 2, 2, 2);
  }

  /**
   * Sets a click event handler to the delete button.
   * It is necessary that the inflation has been done before this method invocation.
   */
  @SuppressWarnings("deprecation")
  private void initializeDeleteButton() {
    ImageView deleteButton = ImageView.class.cast(findViewById(R.id.symbol_view_delete_button));
    deleteButton.setOnTouchListener(deleteKeyEventButtonTouchListener);
    deleteButton.setBackgroundDrawable(
        createButtonBackgroundDrawable(skinType, getResources().getDisplayMetrics().density));
    setMozcDrawable(deleteButton, R.raw.symbol__function__delete);
    deleteButton.setPadding(0, 0, 0, 0);
  }

  TabHost getTabHost() {
    return TabHost.class.cast(findViewById(android.R.id.tabhost));
  }

  ViewPager getCandidateViewPager() {
    return ViewPager.class.cast(findViewById(R.id.symbol_input_candidate_view_pager));
  }

  ImageButton getMajorCategoryButton(SymbolMajorCategory majorCategory) {
    if (majorCategory == null) {
      throw new NullPointerException("majorCategory shouldn't be null.");
    }
    return ImageButton.class.cast(findViewById(majorCategory.buttonResourceId));
  }

  View getEmojiDisabledMessageView() {
    return findViewById(R.id.symbol_emoji_disabled_message_view);
  }

  public void setEmojiEnabled(boolean unicodeEmojiEnabled, boolean carrierEmojiEnabled) {
    this.emojiEnabled = unicodeEmojiEnabled || carrierEmojiEnabled;
    enableEmoji(this.emojiEnabled);
    symbolCandidateStorage.setEmojiEnabled(unicodeEmojiEnabled, carrierEmojiEnabled);
  }

  public void setPasswordField(boolean isPasswordField) {
    this.isPasswordField = isPasswordField;
  }

  @SuppressWarnings("deprecation")
  private void enableEmoji(boolean enableEmoji) {
    if (!isInflated()) {
      return;
    }

    ImageButton imageButton = getMajorCategoryButton(SymbolMajorCategory.EMOJI);
    imageButton.setBackgroundDrawable(
        majorCategoryButtonDrawableFactory.createRightButtonDrawable(enableEmoji));
  }

  /**
   * Resets the status.
   */
  void reset() {
    // the current minor category is also updated in setMajorCategory.
    setMajorCategory(SymbolMajorCategory.SYMBOL);
    deleteKeyEventButtonTouchListener.reset();
  }

  @Override
  public void setVisibility(int visibility) {
    int previousVisibility = getVisibility();
    super.setVisibility(visibility);
    if (viewEventListener != null
        && previousVisibility == View.VISIBLE && visibility != View.VISIBLE) {
      viewEventListener.onCloseSymbolInputView();
    }
  }

  void setSymbolCandidateStorage(SymbolCandidateStorage symbolCandidateStorage) {
    this.symbolCandidateStorage = symbolCandidateStorage;
  }

  void setKeyEventHandler(KeyEventHandler keyEventHandler) {
    deleteKeyEventButtonTouchListener.setKeyEventHandler(keyEventHandler);
  }

  void setCandidateTextDimension(float candidateTextSize, float descriptionTextSize) {
    Preconditions.checkArgument(candidateTextSize > 0);
    Preconditions.checkArgument(descriptionTextSize > 0);

    this.candidateTextSize = candidateTextSize;
    this.desciptionTextSize = descriptionTextSize;
  }

  /**
   * Initializes EmojiProvider selection dialog, if necessary.
   * Exposed as protected for testing purpose.
   */
  protected void maybeInitializeEmojiProviderDialog(Context context) {
    if (emojiProviderDialog != null) {
      return;
    }

    EmojiProviderDialogListener listener = new EmojiProviderDialogListener(context);
    try {
      AlertDialog dialog = new AlertDialog.Builder(context)
          .setTitle(R.string.pref_emoji_provider_type_title)
          .setItems(R.array.pref_emoji_provider_type_entries, listener)
          .create();
      this.emojiProviderDialog = dialog;
    } catch (InflateException e) {
      // Ignore the exception.
    }
  }

  /**
   * Sets the major category to show.
   *
   * The view is updated.
   * The active minor category is also updated.
   *
   * @param newCategory the major category to show.
   */
  protected void setMajorCategory(SymbolMajorCategory newCategory) {
    if (newCategory == null) {
      throw new NullPointerException("newCategory must be non-null.");
    }
    currentMajorCategory = newCategory;

    // Reset the minor category to the default value.
    resetTabText();
    resetCandidateViewPager();
    SymbolMinorCategory minorCategory = currentMajorCategory.getDefaultMinorCategory();
    if (symbolCandidateStorage.getCandidateList(minorCategory).getCandidatesCount() == 0) {
      minorCategory = currentMajorCategory.getMinorCategoryByRelativeIndex(minorCategory, 1);
    }
    int index = newCategory.minorCategories.indexOf(minorCategory);
    getCandidateViewPager().setCurrentItem(index);
    getTabHost().setCurrentTab(index);

    // Update visibility relating attributes.
    for (SymbolMajorCategory majorCategory : SymbolMajorCategory.values()) {
      // Update major category selector button's look and feel.
      ImageButton button = getMajorCategoryButton(majorCategory);
      if (button != null) {
        button.setSelected(majorCategory == newCategory);
        button.setEnabled(majorCategory != newCategory);
      }
    }

    View emojiDisabledMessageView = getEmojiDisabledMessageView();
    if (emojiDisabledMessageView != null) {
      // Show messages about emoji-disabling, if necessary.
      emojiDisabledMessageView.setVisibility(
          newCategory == SymbolMajorCategory.EMOJI && !emojiEnabled ? View.VISIBLE : View.GONE);
    }
  }

  void setEmojiProviderType(EmojiProviderType emojiProviderType) {
    Preconditions.checkNotNull(emojiProviderType);

    this.emojiProviderType = emojiProviderType;
    this.symbolCandidateStorage.setEmojiProviderType(emojiProviderType);
    if (!isInflated()) {
      return;
    }

    resetCandidateViewPager();
  }

  void setViewEventListener(ViewEventListener listener, OnClickListener closeButtonClickListener) {
    if (listener == null) {
      throw new NullPointerException("lister must be non-null.");
    }
    viewEventListener = listener;
    this.closeButtonClickListener = closeButtonClickListener;
  }

  void setSkinType(SkinType skinType) {
    if (this.skinType == skinType) {
      return;
    }

    this.skinType = skinType;
    mozcDrawableFactory.setSkinType(skinType);
    if (!isInflated()) {
      return;
    }

    // Reset the minor category tab, candidate view and major category buttons.
    resetTabBackground();
    resetCandidateViewPager();
    resetMajorCategoryBackground();
  }

  @Override
  public void trimMemory() {
    ViewGroup viewGroup = getCandidateViewPager();
    if (viewGroup == null) {
      return;
    }
    for (int i = 0; i < viewGroup.getChildCount(); ++i) {
      View view = viewGroup.getChildAt(i);
      if (view instanceof MemoryManageable) {
        MemoryManageable.class.cast(view).trimMemory();
      }
    }
  }
}
