/*
 * Copyright (C) 2006 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 android.view;

import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;

import java.util.HashMap;

/**
 * Safe identifier for a window.  This currently allows you to retrieve and observe
 * the input focus state of the window.  Most applications will
 * not use this, instead relying on the simpler (and more efficient) methods available
 * on {@link View}.  This classes is useful when window input interactions need to be
 * done across processes: the class itself is a Parcelable that can be passed to other
 * processes for them to interact with your window, and it provides a limited safe API
 * that doesn't allow the other process to negatively harm your window.
 */
public class WindowId implements Parcelable {
    private final IWindowId mToken;

    /**
     * Subclass for observing changes to the focus state of an {@link WindowId}.
     * You should use the same instance of this class for observing multiple
     * {@link WindowId} objects, since this class is fairly heavy-weight -- the
     * base class includes all of the mechanisms for connecting to and receiving updates
     * from the window.
     */
    public static abstract class FocusObserver {
        final IWindowFocusObserver.Stub mIObserver = new IWindowFocusObserver.Stub() {

            @Override
            public void focusGained(IBinder inputToken) {
                WindowId token;
                synchronized (mRegistrations) {
                    token = mRegistrations.get(inputToken);
                }
                if (mHandler != null) {
                    mHandler.sendMessage(mHandler.obtainMessage(1, token));
                } else {
                    onFocusGained(token);
                }
            }

            @Override
            public void focusLost(IBinder inputToken) {
                WindowId token;
                synchronized (mRegistrations) {
                    token = mRegistrations.get(inputToken);
                }
                if (mHandler != null) {
                    mHandler.sendMessage(mHandler.obtainMessage(2, token));
                } else {
                    onFocusLost(token);
                }
            }
        };

        final HashMap<IBinder, WindowId> mRegistrations
                = new HashMap<IBinder, WindowId>();

        class H extends Handler {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 1:
                        onFocusGained((WindowId)msg.obj);
                        break;
                    case 2:
                        onFocusLost((WindowId)msg.obj);
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
        }

        final Handler mHandler;

        /**
         * Construct a new observer.  This observer will be configured so that all
         * of its callbacks are dispatched on the current calling thread.
         */
        public FocusObserver() {
            mHandler = new H();
        }

        /**
         * Called when one of the monitored windows gains input focus.
         */
        public abstract void onFocusGained(WindowId token);

        /**
         * Called when one of the monitored windows loses input focus.
         */
        public abstract void onFocusLost(WindowId token);
    }

    /**
     * Retrieve the current focus state of the associated window.
     */
    public boolean isFocused() {
        try {
            return mToken.isFocused();
        } catch (RemoteException e) {
            return false;
        }
    }

    /**
     * Start monitoring for changes in the focus state of the window.
     */
    public void registerFocusObserver(FocusObserver observer) {
        synchronized (observer.mRegistrations) {
            if (observer.mRegistrations.containsKey(mToken.asBinder())) {
                throw new IllegalStateException(
                        "Focus observer already registered with input token");
            }
            observer.mRegistrations.put(mToken.asBinder(), this);
            try {
                mToken.registerFocusObserver(observer.mIObserver);
            } catch (RemoteException e) {
            }
        }
    }

    /**
     * Stop monitoring changes in the focus state of the window.
     */
    public void unregisterFocusObserver(FocusObserver observer) {
        synchronized (observer.mRegistrations) {
            if (observer.mRegistrations.remove(mToken.asBinder()) == null) {
                throw new IllegalStateException("Focus observer not registered with input token");
            }
            try {
                mToken.unregisterFocusObserver(observer.mIObserver);
            } catch (RemoteException e) {
            }
        }
    }

    /**
     * Comparison operator on two IntentSender objects, such that true
     * is returned then they both represent the same operation from the
     * same package.
     */
    @Override
    public boolean equals(Object otherObj) {
        if (otherObj instanceof WindowId) {
            return mToken.asBinder().equals(((WindowId) otherObj)
                    .mToken.asBinder());
        }
        return false;
    }

    @Override
    public int hashCode() {
        return mToken.asBinder().hashCode();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(128);
        sb.append("IntentSender{");
        sb.append(Integer.toHexString(System.identityHashCode(this)));
        sb.append(": ");
        sb.append(mToken != null ? mToken.asBinder() : null);
        sb.append('}');
        return sb.toString();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeStrongBinder(mToken.asBinder());
    }

    public static final Parcelable.Creator<WindowId> CREATOR
            = new Parcelable.Creator<WindowId>() {
        public WindowId createFromParcel(Parcel in) {
            IBinder target = in.readStrongBinder();
            return target != null ? new WindowId(target) : null;
        }

        public WindowId[] newArray(int size) {
            return new WindowId[size];
        }
    };

    /** @hide */
    public IWindowId getTarget() {
        return mToken;
    }

    /** @hide */
    public WindowId(IWindowId target) {
        mToken = target;
    }

    /** @hide */
    public WindowId(IBinder target) {
        mToken = IWindowId.Stub.asInterface(target);
    }
}
