/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc.videoengine;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import dalvik.system.DexClassLoader;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.Log;

public class VideoCaptureDeviceInfoAndroid {

  //Context
  Context context;

  // Set this to 2 for VERBOSE logging. 1 for DEBUG
  private static int LOGLEVEL = 0;
  private static boolean VERBOSE = LOGLEVEL > 2;
  private static boolean DEBUG = LOGLEVEL > 1;

  // Private class with info about all available cameras and the capabilities
  public class AndroidVideoCaptureDevice {
    AndroidVideoCaptureDevice() {
      frontCameraType = FrontFacingCameraType.None;
      index = 0;
    }

    public String deviceUniqueName;
    public CaptureCapabilityAndroid captureCapabilies[];
    public FrontFacingCameraType frontCameraType;

    // Orientation of camera as described in
    // android.hardware.Camera.CameraInfo.Orientation
    public int orientation;
    // Camera index used in Camera.Open on Android 2.3 and onwards
    public int index;
  }

  public enum FrontFacingCameraType {
    None, // This is not a front facing camera
    GalaxyS, // Galaxy S front facing camera.
    HTCEvo, // HTC Evo front facing camera
    Android23, // Android 2.3 front facing camera.
  }

  String currentDeviceUniqueId;
  int id;
  List<AndroidVideoCaptureDevice> deviceList;

  public static VideoCaptureDeviceInfoAndroid
  CreateVideoCaptureDeviceInfoAndroid(int in_id, Context in_context) {
    if(DEBUG) {
      Log.d("*WEBRTC*",
            String.format(Locale.US, "VideoCaptureDeviceInfoAndroid"));
    }

    VideoCaptureDeviceInfoAndroid self =
        new VideoCaptureDeviceInfoAndroid(in_id, in_context);
    if(self != null && self.Init() == 0) {
      return self;
    }
    else {
      if(DEBUG) {
        Log.d("*WEBRTC*", "Failed to create VideoCaptureDeviceInfoAndroid.");
      }
    }
    return null;
  }

  private VideoCaptureDeviceInfoAndroid(int in_id,
                                        Context in_context) {
    id = in_id;
    context = in_context;
    deviceList = new ArrayList<AndroidVideoCaptureDevice>();
  }

  private int Init() {
    // Populate the deviceList with available cameras and their capabilities.
    Camera camera = null;
    try{
      if(android.os.Build.VERSION.SDK_INT > 8) {
        // From Android 2.3 and onwards
        for(int i = 0; i < Camera.getNumberOfCameras(); ++i) {
          AndroidVideoCaptureDevice newDevice = new AndroidVideoCaptureDevice();

          Camera.CameraInfo info = new Camera.CameraInfo();
          Camera.getCameraInfo(i, info);
          newDevice.index = i;
          newDevice.orientation=info.orientation;
          if(info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
            newDevice.deviceUniqueName =
                "Camera " + i +", Facing back, Orientation "+ info.orientation;
          }
          else {
            newDevice.deviceUniqueName =
                "Camera " + i +", Facing front, Orientation "+ info.orientation;
            newDevice.frontCameraType = FrontFacingCameraType.Android23;
          }

          camera = Camera.open(i);
          Camera.Parameters parameters = camera.getParameters();
          AddDeviceInfo(newDevice, parameters);
          camera.release();
          camera = null;
          deviceList.add(newDevice);
        }
      }
      else {
        // Prior to Android 2.3
        AndroidVideoCaptureDevice newDevice;
        Camera.Parameters parameters;

        newDevice = new AndroidVideoCaptureDevice();
        camera = Camera.open();
        parameters = camera.getParameters();
        newDevice.deviceUniqueName = "Camera 1, Facing back";
        newDevice.orientation = 90;
        AddDeviceInfo(newDevice, parameters);

        deviceList.add(newDevice);
        camera.release();
        camera=null;

        newDevice = new AndroidVideoCaptureDevice();
        newDevice.deviceUniqueName = "Camera 2, Facing front";
        parameters = SearchOldFrontFacingCameras(newDevice);
        if(parameters != null) {
          AddDeviceInfo(newDevice, parameters);
          deviceList.add(newDevice);
        }
      }
    }
    catch (Exception ex) {
      Log.e("*WEBRTC*", "Failed to init VideoCaptureDeviceInfo ex" +
            ex.getLocalizedMessage());
      return -1;
    }
    VerifyCapabilities();
    return 0;
  }

  // Adds the capture capabilities of the currently opened device
  private void AddDeviceInfo(AndroidVideoCaptureDevice newDevice,
                             Camera.Parameters parameters) {

    List<Size> sizes = parameters.getSupportedPreviewSizes();
    List<Integer> frameRates = parameters.getSupportedPreviewFrameRates();
    int maxFPS=0;
    for(Integer frameRate:frameRates) {
      if(VERBOSE) {
        Log.v("*WEBRTC*",
              "VideoCaptureDeviceInfoAndroid:frameRate " + frameRate);
      }
      if(frameRate > maxFPS) {
        maxFPS = frameRate;
      }
    }

    newDevice.captureCapabilies = new CaptureCapabilityAndroid[sizes.size()];
    for(int i = 0; i < sizes.size(); ++i) {
      Size s = sizes.get(i);
      newDevice.captureCapabilies[i] = new CaptureCapabilityAndroid();
      newDevice.captureCapabilies[i].height = s.height;
      newDevice.captureCapabilies[i].width = s.width;
      newDevice.captureCapabilies[i].maxFPS = maxFPS;
    }
  }

  // Function that make sure device specific capabilities are
  // in the capability list.
  // Ie Galaxy S supports CIF but does not list CIF as a supported capability.
  // Motorola Droid Camera does not work with frame rate above 15fps.
  // http://code.google.com/p/android/issues/detail?id=5514#c0
  private void VerifyCapabilities() {
    // Nexus S or Galaxy S
    if(android.os.Build.DEVICE.equals("GT-I9000") ||
       android.os.Build.DEVICE.equals("crespo")) {
      CaptureCapabilityAndroid specificCapability =
          new CaptureCapabilityAndroid();
      specificCapability.width = 352;
      specificCapability.height = 288;
      specificCapability.maxFPS = 15;
      AddDeviceSpecificCapability(specificCapability);

      specificCapability = new CaptureCapabilityAndroid();
      specificCapability.width = 176;
      specificCapability.height = 144;
      specificCapability.maxFPS = 15;
      AddDeviceSpecificCapability(specificCapability);

      specificCapability = new CaptureCapabilityAndroid();
      specificCapability.width = 320;
      specificCapability.height = 240;
      specificCapability.maxFPS = 15;
      AddDeviceSpecificCapability(specificCapability);
    }
    // Motorola Milestone Camera server does not work at 30fps
    // even though it reports that it can
    if(android.os.Build.MANUFACTURER.equals("motorola") &&
       android.os.Build.DEVICE.equals("umts_sholes")) {
      for(AndroidVideoCaptureDevice device:deviceList) {
        for(CaptureCapabilityAndroid capability:device.captureCapabilies) {
          capability.maxFPS=15;
        }
      }
    }
  }

  private void AddDeviceSpecificCapability(
      CaptureCapabilityAndroid specificCapability) {
    for(AndroidVideoCaptureDevice device:deviceList) {
      boolean foundCapability = false;
      for(CaptureCapabilityAndroid capability:device.captureCapabilies) {
        if(capability.width == specificCapability.width &&
           capability.height == specificCapability.height) {
          foundCapability = true;
          break;
        }
      }
      if(foundCapability==false) {
        CaptureCapabilityAndroid newCaptureCapabilies[]=
            new CaptureCapabilityAndroid[device.captureCapabilies.length+1];
        for(int i = 0; i < device.captureCapabilies.length; ++i) {
          newCaptureCapabilies[i+1] = device.captureCapabilies[i];
        }
        newCaptureCapabilies[0] = specificCapability;
        device.captureCapabilies = newCaptureCapabilies;
      }
    }
  }

  // Returns the number of Capture devices that is supported
  public int NumberOfDevices() {
    return deviceList.size();
  }

  public String GetDeviceUniqueName(int deviceNumber) {
    if(deviceNumber < 0 || deviceNumber >= deviceList.size()) {
      return null;
    }
    return deviceList.get(deviceNumber).deviceUniqueName;
  }

  public CaptureCapabilityAndroid[] GetCapabilityArray (String deviceUniqueId)
  {
    for (AndroidVideoCaptureDevice device: deviceList) {
      if(device.deviceUniqueName.equals(deviceUniqueId)) {
        return (CaptureCapabilityAndroid[]) device.captureCapabilies;
      }
    }
    return null;
  }

  // Returns the camera orientation as described by
  // android.hardware.Camera.CameraInfo.orientation
  public int GetOrientation(String deviceUniqueId) {
    for (AndroidVideoCaptureDevice device: deviceList) {
      if(device.deviceUniqueName.equals(deviceUniqueId)) {
        return device.orientation;
      }
    }
    return -1;
  }

  // Returns an instance of VideoCaptureAndroid.
  public VideoCaptureAndroid AllocateCamera(int id, long context,
                                            String deviceUniqueId) {
    try {
      if(DEBUG) Log.d("*WEBRTC*", "AllocateCamera " + deviceUniqueId);

      Camera camera = null;
      AndroidVideoCaptureDevice deviceToUse = null;
      for (AndroidVideoCaptureDevice device: deviceList) {
        if(device.deviceUniqueName.equals(deviceUniqueId)) {
          // Found the wanted camera
          deviceToUse = device;
          switch(device.frontCameraType) {
            case GalaxyS:
              camera = AllocateGalaxySFrontCamera();
              break;
            case HTCEvo:
              camera = AllocateEVOFrontFacingCamera();
              break;
            default:
              // From Android 2.3 and onwards)
              if(android.os.Build.VERSION.SDK_INT>8)
                camera=Camera.open(device.index);
              else
                camera=Camera.open(); // Default camera
          }
        }
      }

      if(camera == null) {
        return null;
      }
      if(VERBOSE) {
        Log.v("*WEBRTC*", "AllocateCamera - creating VideoCaptureAndroid");
      }

      return new VideoCaptureAndroid(id,context,camera,deviceToUse);

    }catch (Exception ex) {
      Log.e("*WEBRTC*", "AllocateCamera Failed to open camera- ex " +
            ex.getLocalizedMessage());
    }
    return null;
  }

  // Searches for a front facing camera device. This is device specific code.
  private Camera.Parameters
  SearchOldFrontFacingCameras(AndroidVideoCaptureDevice newDevice)
      throws SecurityException, IllegalArgumentException,
      NoSuchMethodException, ClassNotFoundException,
      IllegalAccessException, InvocationTargetException {
    // Check the id of the opened camera device
    // Returns null on X10 and 1 on Samsung Galaxy S.
    Camera camera = Camera.open();
    Camera.Parameters parameters = camera.getParameters();
    String cameraId = parameters.get("camera-id");
    if(cameraId != null && cameraId.equals("1")) {
      // This might be a Samsung Galaxy S with a front facing camera.
      try {
        parameters.set("camera-id", 2);
        camera.setParameters(parameters);
        parameters = camera.getParameters();
        newDevice.frontCameraType = FrontFacingCameraType.GalaxyS;
        newDevice.orientation = 0;
        camera.release();
        return parameters;
      }
      catch (Exception ex) {
        //Nope - it did not work.
        Log.e("*WEBRTC*", "Init Failed to open front camera camera - ex " +
              ex.getLocalizedMessage());
      }
    }
    camera.release();

    //Check for Evo front facing camera
    File file =
        new File("/system/framework/com.htc.hardware.twinCamDevice.jar");
    boolean exists = file.exists();
    if (!exists){
      file =
          new File("/system/framework/com.sprint.hardware.twinCamDevice.jar");
      exists = file.exists();
    }
    if(exists) {
      newDevice.frontCameraType = FrontFacingCameraType.HTCEvo;
      newDevice.orientation = 0;
      Camera evCamera = AllocateEVOFrontFacingCamera();
      parameters = evCamera.getParameters();
      evCamera.release();
      return parameters;
    }
    return null;
  }

  // Returns a handle to HTC front facing camera.
  // The caller is responsible to release it on completion.
  private Camera AllocateEVOFrontFacingCamera()
      throws SecurityException, NoSuchMethodException,
      ClassNotFoundException, IllegalArgumentException,
      IllegalAccessException, InvocationTargetException {
    String classPath = null;
    File file =
        new File("/system/framework/com.htc.hardware.twinCamDevice.jar");
    classPath = "com.htc.hardware.twinCamDevice.FrontFacingCamera";
    boolean exists = file.exists();
    if (!exists){
      file =
          new File("/system/framework/com.sprint.hardware.twinCamDevice.jar");
      classPath = "com.sprint.hardware.twinCamDevice.FrontFacingCamera";
      exists = file.exists();
    }
    if(!exists) {
      return null;
    }

    String dexOutputDir = "";
    if(context != null) {
      dexOutputDir = context.getFilesDir().getAbsolutePath();
      File mFilesDir = new File(dexOutputDir, "dexfiles");
      if(!mFilesDir.exists()){
        //Log.e("*WEBRTCN*", "Directory doesn't exists");
        if(!mFilesDir.mkdirs()) {
          //Log.e("*WEBRTCN*", "Unable to create files directory");
        }
      }
    }

    dexOutputDir += "/dexfiles";

    DexClassLoader loader =
        new DexClassLoader(file.getAbsolutePath(), dexOutputDir,
                           null, ClassLoader.getSystemClassLoader());

    Method method = loader.loadClass(classPath).getDeclaredMethod(
        "getFrontFacingCamera", (Class[]) null);
    Camera camera = (Camera) method.invoke((Object[])null,(Object[]) null);
    return camera;
  }

  // Returns a handle to Galaxy S front camera.
  // The caller is responsible to release it on completion.
  private Camera AllocateGalaxySFrontCamera()
  {
    Camera camera = Camera.open();
    Camera.Parameters parameters = camera.getParameters();
    parameters.set("camera-id",2);
    camera.setParameters(parameters);
    return camera;
  }

}
