/*
 * SimpleDevicePicker
 * Connect SDK
 * 
 * Copyright (c) 2014 LG Electronics.
 * Created by Jason Lai on 19 Jan 2014
 * 
 * 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.connectsdk.device;

import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.content.res.Resources;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;

import com.connectsdk.core.Util;
import com.connectsdk.service.DeviceService;
import com.connectsdk.service.DeviceService.PairingType;
import com.connectsdk.service.command.ServiceCommandError;

/**
 * A device picker that automatically connects to the device
 * and automatically displays pairing dialogs when needed.
 * 
 * NOTE: Most methods MUST be called from the main ui thread.
 */
public class SimpleDevicePicker implements ConnectableDeviceListener {
    protected Activity activity;
    protected DevicePicker picker;
    protected Dialog pickerDialog;
    protected Dialog pairingDialog;

    // Device that we're in the process of connecting to
    protected ConnectableDevice pendingDevice;

    // Connected, active device
    protected ConnectableDevice activeDevice;

    protected int selectDeviceResId;
    protected int simplePairingTitleResId;
    protected int simplePairingPromptResId;
    protected int pinPairingPromptResId;
    protected int connectionFailedResId;

    SimpleDevicePickerListener listener;
    private PairingType pairingType;

    public SimpleDevicePicker(Activity activity) {
        this.activity = activity;
        this.picker = new DevicePicker(activity);

        loadStringIds();
    }

    public void setPairingType(PairingType pairingType) {
        this.pairingType = pairingType;
    }

    /**
     * Get the currently selected device
     * @return current connected device
     */
    public ConnectableDevice getCurrentDevice() {
        return activeDevice;
    }

    protected void loadStringIds() {
        selectDeviceResId = getStringId("connect_sdk_picker_select_device");
        simplePairingTitleResId = getStringId("connect_sdk_pairing_simple_title_tv");
        simplePairingPromptResId = getStringId("connect_sdk_pairing_simple_prompt_tv");
        pinPairingPromptResId = getStringId("connect_sdk_pairing_pin_prompt_tv");
        connectionFailedResId = getStringId("connect_sdk_connection_failed");
    }

    protected int getStringId(String key) {
        // First try to get resource from application
        int id = this.activity.getResources().getIdentifier(key, "string", activity.getPackageName());

        // Then try to get from Connect SDK library
        if (id == 0) {
            id = this.activity.getResources().getIdentifier(key, "string", "com.connectsdk");
        }

        if (id == 0) {
            Log.w("ConnectSDK", "missing string resource for \"" + key + "\"");

            throw new Resources.NotFoundException(key);
        }

        return id;
    }

    public void setListener(SimpleDevicePickerListener listener) {
        this.listener = listener;
    }

    protected void cleanupPending() {
        if (pendingDevice != null) {
            pendingDevice.removeListener(this);
            pendingDevice = null;
        }
    }

    protected void cleanupActive() {
        if (activeDevice != null) {
            activeDevice.removeListener(this);
            activeDevice = null;
        }
    }

    public void showPicker() {
        cleanupPending(); // remove any currently pending device
        hidePicker();

        pickerDialog = picker.getPickerDialog(activity.getString(selectDeviceResId), new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View view, int pos,
                    long id) {
                ConnectableDevice device = (ConnectableDevice) adapter.getItemAtPosition(pos);

                selectDevice(device);
            }
        });

        pickerDialog.show();
    }

    public void hidePicker() {
        if (pickerDialog != null) {
            pickerDialog.dismiss();
            pickerDialog = null;
        }
    }

    /**
     * Connect to a device
     * 
     * @param device
     */
    public void selectDevice(ConnectableDevice device) {
        if (device != null) {
            pendingDevice = device;
            pendingDevice.addListener(this);

            if (listener != null) {
                // Give listener a chance to setup device before connecting
                listener.onPrepareDevice(device);
            }

            if (!device.isConnected()) {
                device.setPairingType(pairingType);
                device.connect();
            } else {
                onDeviceReady(device);
            }
        } else {
            cleanupPending();
        }
    }

    protected Dialog createSimplePairingDialog() {
        PairingDialog dialog = new PairingDialog(activity, pendingDevice);
        return dialog.getSimplePairingDialog(simplePairingTitleResId, simplePairingPromptResId);
    }

    protected Dialog createPinPairingDialog() {
        PairingDialog dialog = new PairingDialog(activity, pendingDevice);
        return dialog.getPairingDialog(pinPairingPromptResId);
    }

    protected void showPairingDialog(PairingType pairingType) {
        switch (pairingType) { 
        case FIRST_SCREEN:
            pairingDialog = createSimplePairingDialog();
            break;

        case PIN_CODE:
            pairingDialog = createPinPairingDialog();
            break;

        case NONE:
        default:
            break;
        }

        if (pairingDialog != null) {
            pairingDialog.show();
        }
    }

    /**
     * Hide the current pairing dialog and cancels the pairing attempt.
     */
    public void hidePairingDialog() {
        // cancel pairing
        if (pairingDialog != null) {
            pairingDialog.dismiss();
            pairingDialog = null;
        }
    }


    @Override
    public void onDeviceReady(final ConnectableDevice device) {
        Util.runOnUI(new Runnable() {
            @Override
            public void run() {
                hidePairingDialog();

                if (device == pendingDevice) {
                    activeDevice = pendingDevice;

                    if (listener != null) {
                        listener.onPickDevice(pendingDevice);
                    }
                    pendingDevice = null;
                }
            }
        });
    }

    @Override
    public void onDeviceDisconnected(final ConnectableDevice device) {
        if (device == pendingDevice) {
            pickFailed(device);
        }

        if (device == activeDevice) {
            cleanupActive();
        }
    }

    @Override
    public void onCapabilityUpdated(ConnectableDevice device, List<String> added, List<String> removed) {
    }

    @Override
    public void onConnectionFailed(ConnectableDevice device, ServiceCommandError error) {
        if (device == pendingDevice) {
            pickFailed(device);
        }

        if (device == activeDevice) {
            cleanupActive();
        }
    }

    @Override
    public void onPairingRequired(ConnectableDevice device, DeviceService service, final PairingType pairingType) {
        Log.d("SimpleDevicePicker", "pairing required for device " + device.getFriendlyName());

        Util.runOnUI(new Runnable() {
            @Override
            public void run() {
                showPairingDialog(pairingType);
            }
        });
    }

    protected void pickFailed(final ConnectableDevice device) {
        Util.runOnUI(new Runnable() {
            @Override
            public void run() {
                if (pendingDevice == device) {
                    // Device failed before successfully picking device
                    if (listener != null) {
                        listener.onPickDeviceFailed(false);
                    }
                }

                cleanupPending();

                Toast.makeText(activity, connectionFailedResId, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

@@ -6055,16 +6055,36 @@
 N_CODE:%0A
+        case MIXED:%0A
         

Add PairingType.MIXED mode support into SimpleDevicePicker