/*
 *  Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
 *  Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
 *
 *  Author: Regis Montoya <r3gis.3R@gmail.com>
 *  Alexandre Lision <alexandre.lision@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */
package org.sflphone.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.sflphone.utils.AccelerometerListener.OrientationListener;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.wifi.WifiManager;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;

/**
 * Class to manage proximity detection while in call.
 * 
 */
public class CallProximityManager implements SensorEventListener, OrientationListener {
    private static final String THIS_FILE = "CallProximityManager";

    private Context mContext;

    private SensorManager sensorManager;
    private PowerManager powerManager;

    // Timeout management of screen locker ui
    // private ScreenLocker mScreenLocker;
    private Boolean useTimeoutOverlay = null;

    // Self management of proximity sensor
    private Sensor proximitySensor;
    private static final float PROXIMITY_THRESHOLD = 5.0f;
    private boolean invertProximitySensor = false;
    private boolean proximitySensorTracked = false;
    private boolean isFirstRun = true;
    private ProximityDirector mDirector = null;

    // The hidden api that uses a wake lock
    private WakeLock proximityWakeLock;

    // The accelerometer
    private AccelerometerListener accelerometerManager;
    private int mOrientation;
    private boolean accelerometerEnabled = false;

    private int WAIT_FOR_PROXIMITY_NEGATIVE = 1;
    // private final static int SCREEN_LOCKER_ACQUIRE_DELAY = "google_sdk".equals(Build.PRODUCT) ? ScreenLocker.WAIT_BEFORE_LOCK_LONG
    // : ScreenLocker.WAIT_BEFORE_LOCK_SHORT;

    private static Method powerLockReleaseIntMethod;

    public interface ProximityDirector {
        public boolean shouldActivateProximity();

        public void onProximityTrackingChanged(boolean acquired);
    }

    public CallProximityManager(Context context, ProximityDirector director) {
        mContext = context;
        mDirector = director;
        // mScreenLocker = screenLocker;

        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        accelerometerManager = new AccelerometerListener(context, this);

        // Try to detect the hidden api
        if (powerManager != null) {
            WifiManager wman = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

            // Try to use powermanager proximity sensor
            try {
                boolean supportProximity = false;
                Field f = PowerManager.class.getDeclaredField("PROXIMITY_SCREEN_OFF_WAKE_LOCK");
                int proximityScreenOffWakeLock = (Integer) f.get(null);
                if (Compatibility.isCompatible(17)) {
                    // Changes of the private API on android 4.2
                    Method method = powerManager.getClass().getDeclaredMethod("isWakeLockLevelSupported", int.class);
                    supportProximity = (Boolean) method.invoke(powerManager, proximityScreenOffWakeLock);
                    Log.d(THIS_FILE, "Use 4.2 detection way for proximity sensor detection. Result is " + supportProximity);
                } else {
                    Method method = powerManager.getClass().getDeclaredMethod("getSupportedWakeLockFlags");
                    int supportedFlags = (Integer) method.invoke(powerManager);
                    Log.d(THIS_FILE, "Proxmity flags supported : " + supportedFlags);
                    supportProximity = ((supportedFlags & proximityScreenOffWakeLock) != 0x0);
                }
                if (supportProximity) {
                    Log.d(THIS_FILE, "We can use native screen locker !!");
                    proximityWakeLock = powerManager.newWakeLock(proximityScreenOffWakeLock, "org.sflphone.CallProximity");
                    proximityWakeLock.setReferenceCounted(false);
                }

            } catch (Exception e) {
                Log.d(THIS_FILE, "Impossible to get power manager supported wake lock flags ");
            }
            if (powerLockReleaseIntMethod == null) {
                try {
                    powerLockReleaseIntMethod = proximityWakeLock.getClass().getDeclaredMethod("release", int.class);

                } catch (Exception e) {
                    Log.d(THIS_FILE, "Impossible to get power manager release with it");
                }

            }
        }

        // Try to detect a proximity sensor as fallback
        if (proximityWakeLock == null) {
            proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
            // invertProximitySensor = SipConfigManager.getPreferenceBooleanValue(context, SipConfigManager.INVERT_PROXIMITY_SENSOR);
        }

    }

    public synchronized void startTracking() {
        // If we should manage it ourselves
        if (proximitySensor != null && !proximitySensorTracked) {
            // Fall back to manual mode
            isFirstRun = true;
            Log.d(THIS_FILE, "Register sensor");
            sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
            proximitySensorTracked = true;
        }
        if (!accelerometerEnabled) {
            accelerometerManager.enable(true);
            accelerometerEnabled = true;
        }
    }

    public synchronized void stopTracking() {
        if (proximitySensor != null && proximitySensorTracked) {
            proximitySensorTracked = false;
            sensorManager.unregisterListener(this);
            Log.d(THIS_FILE, "Unregister to sensor is done !!!");
        }
        if (accelerometerEnabled) {
            accelerometerManager.enable(false);
            accelerometerEnabled = false;
        }
        // mScreenLocker.tearDown();
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // Log.d(THIS_FILE, "Tracked : "+proximitySensorTracked);
        if (proximitySensorTracked && !isFirstRun) {
            float distance = event.values[0];
            boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD && distance < event.sensor.getMaximumRange());
            if (invertProximitySensor) {
                active = !active;
            }
            Log.d(THIS_FILE, "Distance is now " + distance);

            boolean isValidCallState = false;
            if (mDirector != null) {
                isValidCallState = mDirector.shouldActivateProximity();
            }

            if (isValidCallState && active) {
                // mScreenLocker.show();
                if (mDirector != null) {
                    mDirector.onProximityTrackingChanged(true);
                }
            } else {
                // mScreenLocker.hide();
                if (mDirector != null) {
                    mDirector.onProximityTrackingChanged(false);
                }
            }

        }
        if (isFirstRun) {
            isFirstRun = false;
        }
    }

    private boolean isProximityWakeHeld = false;

    /**
     * Release any lock taken by the proximity sensor
     */
    public synchronized void release(int flag) {
        if (proximityWakeLock != null && isProximityWakeHeld) {
            boolean usedNewRelease = false;
            if (powerLockReleaseIntMethod != null) {
                try {
                    powerLockReleaseIntMethod.invoke(proximityWakeLock, flag);
                    usedNewRelease = true;
                    // Log.d(THIS_FILE, "CALL NEW RELEASE WITH FLAG " + flag);
                } catch (Exception e) {
                    Log.d(THIS_FILE, "Error calling new release method ", e);
                }
            }
            if (!usedNewRelease) {
                proximityWakeLock.release();
            }
            isProximityWakeHeld = false;
        }

        if (shouldUseTimeoutOverlay()) {
            // mScreenLocker.hide();
        }
        // Notify
        if (mDirector != null) {
            mDirector.onProximityTrackingChanged(false);
        }
    }

    public synchronized void acquire() {
        if (proximityWakeLock != null && !isProximityWakeHeld) {
            proximityWakeLock.acquire();
            isProximityWakeHeld = true;
        }
        if (shouldUseTimeoutOverlay()) {
            // mScreenLocker.delayedLock(SCREEN_LOCKER_ACQUIRE_DELAY);
        }
        // Notify
        if (mDirector != null) {
            mDirector.onProximityTrackingChanged(true);
        }
    }

    /**
     * Update proximity lock mode depending on current state
     */
    public synchronized void updateProximitySensorMode() {

        // We do not keep the screen off when the user is outside in-call screen and we are
        // horizontal, but we do not force it on when we become horizontal until the
        // proximity sensor goes negative.
        boolean horizontal = (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);

        boolean activeRegardingCalls = false;
        if (mDirector != null) {
            activeRegardingCalls = mDirector.shouldActivateProximity();
        }

        //Log.d(THIS_FILE, "Horizontal : " + horizontal + " and activate for calls " + activeRegardingCalls);
        if (activeRegardingCalls && !horizontal) {
            // Phone is in use! Arrange for the screen to turn off
            // automatically when the sensor detects a close object.
            acquire();
        } else {
            // Phone is either idle, or ringing. We don't want any
            // special proximity sensor behavior in either case.
            int flags = (!horizontal ? 0 : WAIT_FOR_PROXIMITY_NEGATIVE);
            release(flags);
        }
    }

    /**
     * Should the application display the overlay after a timeout.
     * 
     * @return false if we are in table mode or if proximity sensor can be used
     */
    private boolean shouldUseTimeoutOverlay() {
        if (useTimeoutOverlay == null) {
            useTimeoutOverlay = proximitySensor == null && proximityWakeLock == null && !Compatibility.isTabletScreen(mContext);
        }
        return useTimeoutOverlay;
    }

    public void restartTimer() {
        if (shouldUseTimeoutOverlay()) {
            // mScreenLocker.delayedLock(ScreenLocker.WAIT_BEFORE_LOCK_LONG);
        }
    }

    @Override
    public void orientationChanged(int orientation) {
        mOrientation = orientation;
        updateProximitySensorMode();
    }

}