// Copyright 2010-2015, 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.preference;

import org.mozc.android.inputmethod.japanese.ViewManagerInterface.LayoutAdjustment;
import org.mozc.android.inputmethod.japanese.emoji.EmojiProviderType;
import org.mozc.android.inputmethod.japanese.resources.R;
import org.mozc.android.inputmethod.japanese.view.SkinType;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;

import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;

/**
 * This class expresses the client-side preferences which corresponds to current
 * device configuration.
 *
 */
public class ClientSidePreference {
  /**
   * Keyboard layout.
   * A user can choose one of the layouts, and then the keyboard (sub)layouts are activated.
   *
   * Here "(sub)layouts" means that for example QWERTY layout contains following (sub)layouts;
   * QWERTY for Hiragana, QWERTY for Alphabet, QWERTY Symbol for Hiragana,
   * and QWERTY Symbol for Alphabet.
   * If a user choose a keyboard layout, (s)he can switch among the (sub)layouts which
   * belong to the selected layout.
   */
  public enum KeyboardLayout {
    TWELVE_KEYS(1),
    QWERTY(2),
    GODAN(3),
    ;

    // ID for usage stats.
    private final int id;

    private KeyboardLayout(int id) {
      this.id = id;
    }

    public int getId() {
      return id;
    }
  }

  /**
   * A user's input style.
   */
  public enum InputStyle {
    TOGGLE,
    FLICK,
    TOGGLE_FLICK,
  }

  /**
   *  Hardware Keyboard Mapping.
   */
  public enum HardwareKeyMap {
    DEFAULT,
    JAPANESE109A,
  }

  private final boolean isHapticFeedbackEnabled;
  private final long hapticFeedbackDuration;
  private final boolean isSoundFeedbackEnabled;
  private final int soundFeedbackVolume;
  private final boolean isPopupFeedbackEnabled;
  private final KeyboardLayout keyboardLayout;
  private final InputStyle inputStyle;
  private final boolean qwertyLayoutForAlphabet;
  private final boolean fullscreenMode;
  private final int flickSensitivity;
  private final EmojiProviderType emojiProviderType;
  private final HardwareKeyMap hardwareKeyMap;
  private final SkinType skinType;
  private final boolean isMicrophoneButtonEnabled;
  private final LayoutAdjustment layoutAdjustment;

  /** Percentage of keyboard height */
  private final int keyboardHeightRatio;

  /**
   * If you want to use this method,
   * consider using {@link #ClientSidePreference(SharedPreferences, Resources, int)} instead.
   */
  @VisibleForTesting public ClientSidePreference(
      boolean isHapticFeedbackEnabled, long hapticFeedbackDuration, boolean isSoundFeedbackEnabled,
      int soundFeedbackVolume, boolean isPopupFeedbackEnabled, KeyboardLayout keyboardLayout,
      InputStyle inputStyle, boolean qwertyLayoutForAlphabet, boolean fullscreenMode,
      int flickSensitivity, EmojiProviderType emojiProviderType, HardwareKeyMap hardwareKeyMap,
      SkinType skinType, boolean isMicrophoneButtonEnabled, LayoutAdjustment layoutAdjustment,
      int keyboardHeightRatio) {
    this.isHapticFeedbackEnabled = isHapticFeedbackEnabled;
    this.hapticFeedbackDuration = hapticFeedbackDuration;
    this.isSoundFeedbackEnabled = isSoundFeedbackEnabled;
    this.soundFeedbackVolume = soundFeedbackVolume;
    this.isPopupFeedbackEnabled = isPopupFeedbackEnabled;
    this.keyboardLayout = Preconditions.checkNotNull(keyboardLayout);
    this.inputStyle = Preconditions.checkNotNull(inputStyle);
    this.qwertyLayoutForAlphabet = qwertyLayoutForAlphabet;
    this.fullscreenMode = fullscreenMode;
    this.flickSensitivity = flickSensitivity;
    this.emojiProviderType = Preconditions.checkNotNull(emojiProviderType);
    this.hardwareKeyMap = Preconditions.checkNotNull(hardwareKeyMap);
    this.skinType = Preconditions.checkNotNull(skinType);
    this.isMicrophoneButtonEnabled = isMicrophoneButtonEnabled;
    this.layoutAdjustment = Preconditions.checkNotNull(layoutAdjustment);
    this.keyboardHeightRatio = keyboardHeightRatio;
  }

  public ClientSidePreference(
      SharedPreferences sharedPreferences, Resources resources, int deviceOrientation) {
    Preconditions.checkNotNull(sharedPreferences);

    isHapticFeedbackEnabled =
        sharedPreferences.getBoolean(PreferenceUtil.PREF_HAPTIC_FEEDBACK_KEY, false);
    hapticFeedbackDuration =
        sharedPreferences.getInt(PreferenceUtil.PREF_HAPTIC_FEEDBACK_DURATION_KEY, 30);
    isSoundFeedbackEnabled =
        sharedPreferences.getBoolean(PreferenceUtil.PREF_SOUND_FEEDBACK_KEY, false);
    soundFeedbackVolume =
        sharedPreferences.getInt(PreferenceUtil.PREF_SOUND_FEEDBACK_VOLUME_KEY, 50);
    isPopupFeedbackEnabled =
        sharedPreferences.getBoolean(PreferenceUtil.PREF_POPUP_FEEDBACK_KEY, true);
    isMicrophoneButtonEnabled =
        sharedPreferences.getBoolean(PreferenceUtil.PREF_VOICE_INPUT_KEY, true);

    String keyboardLayoutKey;
    String inputStyleKey;
    String qwertyLayoutForAlphabetKey;
    String flickSensitivityKey;
    String layoutAdjustmentKey;
    String keyboardHeightRatioKey;

    if (PreferenceUtil.isLandscapeKeyboardSettingActive(sharedPreferences, deviceOrientation)) {
      keyboardLayoutKey = PreferenceUtil.PREF_LANDSCAPE_KEYBOARD_LAYOUT_KEY;
      inputStyleKey = PreferenceUtil.PREF_LANDSCAPE_INPUT_STYLE_KEY;
      qwertyLayoutForAlphabetKey = PreferenceUtil.PREF_LANDSCAPE_QWERTY_LAYOUT_FOR_ALPHABET_KEY;
      flickSensitivityKey = PreferenceUtil.PREF_LANDSCAPE_FLICK_SENSITIVITY_KEY;
      layoutAdjustmentKey = PreferenceUtil.PREF_LANDSCAPE_LAYOUT_ADJUSTMENT_KEY;
      keyboardHeightRatioKey = PreferenceUtil.PREF_LANDSCAPE_KEYBOARD_HEIGHT_RATIO_KEY;
    } else {
      keyboardLayoutKey = PreferenceUtil.PREF_PORTRAIT_KEYBOARD_LAYOUT_KEY;
      inputStyleKey = PreferenceUtil.PREF_PORTRAIT_INPUT_STYLE_KEY;
      qwertyLayoutForAlphabetKey = PreferenceUtil.PREF_PORTRAIT_QWERTY_LAYOUT_FOR_ALPHABET_KEY;
      flickSensitivityKey = PreferenceUtil.PREF_PORTRAIT_FLICK_SENSITIVITY_KEY;
      layoutAdjustmentKey = PreferenceUtil.PREF_PORTRAIT_LAYOUT_ADJUSTMENT_KEY;
      keyboardHeightRatioKey = PreferenceUtil.PREF_PORTRAIT_KEYBOARD_HEIGHT_RATIO_KEY;
    }

    // Don't apply pref_portrait_keyboard_settings_for_landscape for fullscreen mode.
    String fullscreenKey = (deviceOrientation == Configuration.ORIENTATION_LANDSCAPE)
        ? PreferenceUtil.PREF_LANDSCAPE_FULLSCREEN_KEY
        : PreferenceUtil.PREF_PORTRAIT_FULLSCREEN_KEY;

    keyboardLayout = PreferenceUtil.getEnum(
        sharedPreferences, keyboardLayoutKey,
        KeyboardLayout.class, KeyboardLayout.TWELVE_KEYS, KeyboardLayout.GODAN);
    inputStyle = PreferenceUtil.getEnum(
        sharedPreferences, inputStyleKey,
        InputStyle.class, InputStyle.TOGGLE_FLICK);
    qwertyLayoutForAlphabet =
        sharedPreferences.getBoolean(qwertyLayoutForAlphabetKey, false);
    // On large screen device, pref_portrait_fullscreen_key and
    // pref_landscape_fullscreen_key are omitted
    // so below default value "false" is applied.
    fullscreenMode =
        sharedPreferences.getBoolean(fullscreenKey, false);
    flickSensitivity = sharedPreferences.getInt(flickSensitivityKey, 0);

    emojiProviderType = PreferenceUtil.getEnum(
        sharedPreferences, PreferenceUtil.PREF_EMOJI_PROVIDER_TYPE, EmojiProviderType.class,
        EmojiProviderType.NONE);

    hardwareKeyMap = PreferenceUtil.getEnum(
        sharedPreferences, PreferenceUtil.PREF_HARDWARE_KEYMAP, HardwareKeyMap.class,
        HardwareKeyMap.DEFAULT);
    skinType = PreferenceUtil.getEnum(
        sharedPreferences, resources.getString(R.string.pref_skin_type_key),
        SkinType.class, SkinType.valueOf(resources.getString(R.string.pref_skin_type_default)));
    layoutAdjustment = PreferenceUtil.getEnum(
        sharedPreferences, layoutAdjustmentKey, LayoutAdjustment.class, LayoutAdjustment.FILL);
    keyboardHeightRatio = sharedPreferences.getInt(keyboardHeightRatioKey, 100);
  }

  public boolean isHapticFeedbackEnabled() {
    return isHapticFeedbackEnabled;
  }

  public long getHapticFeedbackDuration() {
    return hapticFeedbackDuration;
  }

  public boolean isSoundFeedbackEnabled() {
    return isSoundFeedbackEnabled;
  }

  public int getSoundFeedbackVolume() {
    return soundFeedbackVolume;
  }

  public boolean isPopupFeedbackEnabled() {
    return isPopupFeedbackEnabled;
  }

  public KeyboardLayout getKeyboardLayout() {
    return keyboardLayout;
  }

  public InputStyle getInputStyle() {
    return inputStyle;
  }

  public boolean isQwertyLayoutForAlphabet() {
    return qwertyLayoutForAlphabet;
  }

  public boolean isFullscreenMode() {
    return fullscreenMode;
  }

  public int getFlickSensitivity() {
    return flickSensitivity;
  }

  public EmojiProviderType getEmojiProviderType() {
    return emojiProviderType;
  }

  public HardwareKeyMap getHardwareKeyMap() {
    return hardwareKeyMap;
  }

  public SkinType getSkinType() {
    return skinType;
  }

  public boolean isMicrophoneButtonEnabled() {
    return isMicrophoneButtonEnabled;
  }

  public LayoutAdjustment getLayoutAdjustment() {
    return layoutAdjustment;
  }

  public int getKeyboardHeightRatio() {
    return keyboardHeightRatio;
  }
}
