package org.solovyev.android.calculator.keyboard;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.ActivityLauncher;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.Calculator;
import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.Keyboard;
import org.solovyev.android.calculator.Preferences;
import org.solovyev.android.calculator.buttons.CppButton;
import org.solovyev.android.calculator.memory.Memory;
import org.solovyev.android.views.Adjuster;
import org.solovyev.android.views.dragbutton.DirectionDragButton;
import org.solovyev.android.views.dragbutton.DirectionDragImageButton;
import org.solovyev.android.views.dragbutton.DirectionDragListener;
import org.solovyev.android.views.dragbutton.DirectionDragView;
import org.solovyev.android.views.dragbutton.Drag;
import org.solovyev.android.views.dragbutton.DragDirection;
import org.solovyev.android.views.dragbutton.DragEvent;
import org.solovyev.android.views.dragbutton.DragView;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import dagger.Lazy;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING;
import static android.view.HapticFeedbackConstants.KEYBOARD_TAP;
import static org.solovyev.android.calculator.App.cast;
import static org.solovyev.android.calculator.Preferences.Gui.Mode.simple;
public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener {
public static float getTextScale(@NonNull Context context) {
return App.isTablet(context) ? 0.4f : 0.5f;
}
public static final float IMAGE_SCALE = 0.5f;
public static final float IMAGE_SCALE_ERASE = 0.4f;
@NonNull
private final List<DragView> dragButtons = new ArrayList<>();
@NonNull
protected final DirectionDragListener listener;
@Inject
SharedPreferences preferences;
@Inject
Keyboard keyboard;
@Inject
Editor editor;
@Inject
Calculator calculator;
@Inject
ActivityLauncher launcher;
@Inject
Lazy<Memory> memory;
protected int orientation = ORIENTATION_PORTRAIT;
private int textSize;
private Preferences.Gui.Mode mode;
private final float textScale;
public BaseKeyboardUi(@NonNull Application application) {
listener = new DirectionDragListener(application) {
@Override
protected boolean onDrag(@NonNull View view, @NonNull DragEvent event, @NonNull DragDirection direction) {
if (!Drag.hasDirectionText(view, direction)) {
return false;
}
final DirectionDragView dragView = (DirectionDragView) view;
final String text = dragView.getText(direction).getValue();
if (TextUtils.isEmpty(text)) {
// hasDirectionText should return false for empty text
Check.shouldNotHappen();
return false;
}
keyboard.buttonPressed(text);
return true;
}
};
textScale = getTextScale(application);
}
public static void adjustButton(@NonNull View button) {
if (button instanceof TextView) {
Adjuster.adjustText((TextView) button, getTextScale(button.getContext()));
} else if (button instanceof DirectionDragImageButton) {
Adjuster.adjustText(((DirectionDragImageButton) button), AdjusterHelper.instance, getTextScale(button.getContext()), 0);
Adjuster.adjustImage((ImageView) button, IMAGE_SCALE);
} else if (button instanceof ImageView) {
Adjuster.adjustImage((ImageView) button, IMAGE_SCALE);
}
}
@Override
public void onClick(View v) {
final CppButton button = CppButton.getById(v.getId());
if (button == null) {
Check.shouldNotHappen();
return;
}
onClick(v, button.action);
}
public void onCreateView(@Nonnull Activity activity, @Nonnull View view) {
cast(activity.getApplication()).getComponent().inject(this);
preferences.registerOnSharedPreferenceChangeListener(this);
orientation = App.getScreenOrientation(activity);
mode = Preferences.Gui.mode.getPreferenceNoError(preferences);
textSize = calculateTextSize(activity);
}
protected final void prepareButton(@Nullable View button) {
if (button == null) {
return;
}
// we call android.view.View.performHapticFeedback(int, int) from #onClick
button.setHapticFeedbackEnabled(false);
button.setOnClickListener(this);
}
protected final void prepareButton(@Nullable DirectionDragButton button) {
if (button == null) {
return;
}
dragButtons.add(button);
button.setVibrateOnDrag(keyboard.isVibrateOnKeypress());
button.setHighContrast(keyboard.isHighContrast());
prepareButton((View) button);
button.setOnDragListener(listener);
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
Adjuster.adjustText(button, textScale);
}
protected final void hideText(@Nullable DirectionDragView button, @Nonnull DragDirection... directions) {
if (button == null) {
return;
}
for (DragDirection direction : directions) {
hideText(button, direction);
}
}
protected final void hideText(@Nullable DirectionDragView button, @Nonnull DragDirection direction) {
if (button == null) {
return;
}
button.getText(direction).setVisible(false);
}
public void onDestroyView() {
dragButtons.clear();
preferences.unregisterOnSharedPreferenceChangeListener(this);
}
public static int calculateTextSize(@Nonnull Activity activity) {
final boolean portrait = App.getScreenOrientation(activity) == ORIENTATION_PORTRAIT;
final DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
final int buttonsCount = portrait ? 5 : 4;
final int buttonsWeight = portrait ? (2 + 1 + buttonsCount) : (2 + buttonsCount);
final int buttonSize = metrics.heightPixels / buttonsWeight;
return 5 * buttonSize / 12;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (Preferences.Gui.vibrateOnKeypress.isSameKey(key)) {
final boolean vibrate = Preferences.Gui.vibrateOnKeypress.getPreference(preferences);
for (DragView dragButton : dragButtons) {
dragButton.setVibrateOnDrag(vibrate);
}
} else if (Preferences.Gui.highContrast.isSameKey(key)) {
final boolean highContrast = Preferences.Gui.highContrast.getPreference(preferences);
for (DragView dragButton : dragButtons) {
dragButton.setHighContrast(highContrast);
}
}
}
protected boolean isSimpleMode() {
return mode == simple;
}
protected final void onClick(@Nonnull View v, @Nonnull String s) {
if (!keyboard.buttonPressed(s)) {
return;
}
if (!keyboard.isVibrateOnKeypress()) {
return;
}
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
private static class AdjusterHelper implements Adjuster.Helper<DirectionDragImageButton> {
public static AdjusterHelper instance = new AdjusterHelper();
@Override
public void apply(@NonNull DirectionDragImageButton view, float textSize) {
view.setTextSize(textSize);
}
@Override
public float getTextSize(@NonNull DirectionDragImageButton view) {
return view.getTextSize();
}
}
}