/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.multiclientinputmethod;

import android.inputmethodservice.MultiClientInputMethodServiceDelegate;
import android.os.Bundle;
import android.os.Looper;
import android.os.ResultReceiver;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;

final class ClientCallbackImpl implements MultiClientInputMethodServiceDelegate.ClientCallback {
    private static final String TAG = "ClientCallbackImpl";
    private static final boolean DEBUG = false;

    private final MultiClientInputMethodServiceDelegate mDelegate;
    private final SoftInputWindowManager mSoftInputWindowManager;
    private final int mClientId;
    private final int mUid;
    private final int mPid;
    private final int mSelfReportedDisplayId;
    private final KeyEvent.DispatcherState mDispatcherState;
    private final Looper mLooper;
    private final MultiClientInputMethod mInputMethod;

    ClientCallbackImpl(MultiClientInputMethod inputMethod,
            MultiClientInputMethodServiceDelegate delegate,
            SoftInputWindowManager softInputWindowManager, int clientId, int uid, int pid,
            int selfReportedDisplayId) {
        mInputMethod = inputMethod;
        mDelegate = delegate;
        mSoftInputWindowManager = softInputWindowManager;
        mClientId = clientId;
        mUid = uid;
        mPid = pid;
        mSelfReportedDisplayId = selfReportedDisplayId;
        mDispatcherState = new KeyEvent.DispatcherState();
        // For simplicity, we use the main looper for this sample.
        // To use other looper thread, make sure that the IME Window also runs on the same looper
        // and introduce an appropriate synchronization mechanism instead of directly accessing
        // MultiClientInputMethod#mDisplayToLastClientId.
        mLooper = Looper.getMainLooper();
    }

    KeyEvent.DispatcherState getDispatcherState() {
        return mDispatcherState;
    }

    Looper getLooper() {
        return mLooper;
    }

    @Override
    public void onAppPrivateCommand(String action, Bundle data) {
    }

    @Override
    public void onDisplayCompletions(CompletionInfo[] completions) {
    }

    @Override
    public void onFinishSession() {
        if (DEBUG) {
            Log.v(TAG, "onFinishSession clientId=" + mClientId);
        }
        final SoftInputWindow window =
                mSoftInputWindowManager.getSoftInputWindow(mSelfReportedDisplayId);
        if (window == null) {
            return;
        }
        // SoftInputWindow also needs to be cleaned up when this IME client is still associated with
        // it.
        if (mClientId == window.getClientId()) {
            window.onFinishClient();
        }
    }

    @Override
    public void onHideSoftInput(int flags, ResultReceiver resultReceiver) {
        if (DEBUG) {
            Log.v(TAG, "onHideSoftInput clientId=" + mClientId + " flags=" + flags);
        }
        final SoftInputWindow window =
                mSoftInputWindowManager.getSoftInputWindow(mSelfReportedDisplayId);
        if (window == null) {
            return;
        }
        // Seems that the Launcher3 has a bug to call onHideSoftInput() too early so we cannot
        // enforce clientId check yet.
        // TODO: Check clientId like we do so for onShowSoftInput().
        window.hide();
    }

    @Override
    public void onShowSoftInput(int flags, ResultReceiver resultReceiver) {
        if (DEBUG) {
            Log.v(TAG, "onShowSoftInput clientId=" + mClientId + " flags=" + flags);
        }
        final SoftInputWindow window =
                mSoftInputWindowManager.getSoftInputWindow(mSelfReportedDisplayId);
        if (window == null) {
            return;
        }
        if (mClientId != window.getClientId()) {
            Log.w(TAG, "onShowSoftInput() from a background client is ignored."
                    + " windowClientId=" + window.getClientId()
                    + " clientId=" + mClientId);
            return;
        }
        window.show();
    }

    @Override
    public void onStartInputOrWindowGainedFocus(InputConnection inputConnection,
            EditorInfo editorInfo, int startInputFlags, int softInputMode, int targetWindowHandle) {
        if (DEBUG) {
            Log.v(TAG, "onStartInputOrWindowGainedFocus clientId=" + mClientId
                    + " editorInfo=" + editorInfo
                    + " startInputFlags="
                    + InputMethodDebug.startInputFlagsToString(startInputFlags)
                    + " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
                    + " targetWindowHandle=" + targetWindowHandle);
        }

        final int state = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
        final boolean forwardNavigation =
                (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;

        final SoftInputWindow window =
                mSoftInputWindowManager.getOrCreateSoftInputWindow(mSelfReportedDisplayId);
        if (window == null) {
            return;
        }

        if (window.getTargetWindowHandle() != targetWindowHandle) {
            // Target window has changed.  Report new IME target window to the system.
            mDelegate.reportImeWindowTarget(
                    mClientId, targetWindowHandle, window.getWindow().getAttributes().token);
        }
        final int lastClientId = mInputMethod.mDisplayToLastClientId.get(mSelfReportedDisplayId);
        if (lastClientId != mClientId) {
            // deactivate previous client and activate current.
            mDelegate.setActive(lastClientId, false /* active */);
            mDelegate.setActive(mClientId, true /* active */);
        }
        if (inputConnection == null || editorInfo == null) {
            // Placeholder InputConnection case.
            if (window.getClientId() == mClientId) {
                // Special hack for temporary focus changes (e.g. notification shade).
                // If we have already established a connection to this client, and if a placeholder
                // InputConnection is notified, just ignore this event.
            } else {
                window.onDummyStartInput(mClientId, targetWindowHandle);
            }
        } else {
            window.onStartInput(mClientId, targetWindowHandle, inputConnection);
        }

        switch (state) {
            case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
                if (forwardNavigation) {
                    window.show();
                }
                break;
            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
                window.show();
                break;
            case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
                if (forwardNavigation) {
                    window.hide();
                }
                break;
            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
                window.hide();
                break;
        }
        mInputMethod.mDisplayToLastClientId.put(mSelfReportedDisplayId, mClientId);
    }

    @Override
    public void onToggleSoftInput(int showFlags, int hideFlags) {
        // TODO: Implement
        Log.w(TAG, "onToggleSoftInput is not yet implemented. clientId=" + mClientId
                + " showFlags=" + showFlags + " hideFlags=" + hideFlags);
    }

    @Override
    public void onUpdateCursorAnchorInfo(CursorAnchorInfo info) {
    }

    @Override
    public void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd,
            int candidatesStart, int candidatesEnd) {
    }

    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        return false;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (DEBUG) {
            Log.v(TAG, "onKeyDown clientId=" + mClientId + " keyCode=" + keyCode
                    + " event=" + event);
        }
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            final SoftInputWindow window =
                    mSoftInputWindowManager.getSoftInputWindow(mSelfReportedDisplayId);
            if (window != null && window.isShowing()) {
                event.startTracking();
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        return false;
    }

    @Override
    public boolean onKeyMultiple(int keyCode, KeyEvent event) {
        return false;
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (DEBUG) {
            Log.v(TAG, "onKeyUp clientId=" + mClientId + "keyCode=" + keyCode
                    + " event=" + event);
        }
        if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) {
            final SoftInputWindow window =
                    mSoftInputWindowManager.getSoftInputWindow(mSelfReportedDisplayId);
            if (window != null && window.isShowing()) {
                window.hide();
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        return false;
    }
}
