/*
 * Copyright (C) 2016 Google Inc.
 *
 * 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.googlecode.android_scripting.facade.media;

import android.app.Service;
import android.content.Intent;
import android.media.MediaRecorder;
import android.net.Uri;
import android.provider.MediaStore;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.WindowManager;

import com.googlecode.android_scripting.BaseApplication;
import com.googlecode.android_scripting.FutureActivityTaskExecutor;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.AndroidFacade;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.future.FutureActivityTask;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcDefault;
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * A facade for recording media.
 *
 * Guidance notes: Use e.g. '/sdcard/file.ext' for your media destination file. A file extension of
 * mpg will use the default settings for format and codec (often h263 which won't work with common
 * PC media players). A file extension of mp4 or 3gp will use the appropriate format with the (more
 * common) h264 codec. A video player such as QQPlayer (from the android market) plays both codecs
 * and uses the composition matrix (embedded in the video file) to correct for image rotation. Many
 * PC based media players ignore this matrix. Standard video sizes may be specified.
 *
 * @author Felix Arends (felix.arends@gmail.com)
 * @author Damon Kohler (damonkohler@gmail.com)
 * @author John Karwatzki (jokar49@gmail.com)
 */
public class MediaRecorderFacade extends RpcReceiver {

  private final MediaRecorder mMediaRecorder = new MediaRecorder();
  private final Service mService;

  public MediaRecorderFacade(FacadeManager manager) {
    super(manager);
    mService = manager.getService();
  }

  @Rpc(description = "Records audio from the microphone and saves it to the given location.")
  public void recorderStartMicrophone(@RpcParameter(name = "targetPath") String targetPath)
      throws IOException {
    startAudioRecording(targetPath, MediaRecorder.AudioSource.MIC);
  }

  @Rpc(description = "Records video from the camera and saves it to the given location. "
      + "\nDuration specifies the maximum duration of the recording session. "
      + "\nIf duration is 0 this method will return and the recording will only be stopped "
      + "\nwhen recorderStop is called or when a scripts exits. "
      + "\nOtherwise it will block for the time period equal to the duration argument."
      + "\nvideoSize: 0=160x120, 1=320x240, 2=352x288, 3=640x480, 4=800x480.")
  public void recorderStartVideo(@RpcParameter(name = "targetPath") String targetPath,
      @RpcParameter(name = "duration") @RpcDefault("0") Integer duration,
      @RpcParameter(name = "videoSize") @RpcDefault("1") Integer videoSize) throws Exception {
    int ms = convertSecondsToMilliseconds(duration);
    startVideoRecording(new File(targetPath), ms, videoSize);
  }

  private void startVideoRecording(File file, int milliseconds, int videoSize) throws Exception {
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    int audioSource = MediaRecorder.AudioSource.MIC;
    try {
      Field source = Class.forName("android.media.MediaRecorder$AudioSource").getField("CAMCORDER");
      source.getInt(null);
    } catch (Exception e) {
      Log.e(e);
    }
    int xSize;
    int ySize;
    switch (videoSize) {
    case 0:
      xSize = 160;
      ySize = 120;
      break;
    case 1:
      xSize = 320;
      ySize = 240;
      break;
    case 2:
      xSize = 352;
      ySize = 288;
      break;
    case 3:
      xSize = 640;
      ySize = 480;
      break;
    case 4:
      xSize = 800;
      ySize = 480;
      break;
    default:
      xSize = 320;
      ySize = 240;
      break;
    }

    mMediaRecorder.setAudioSource(audioSource);
    String extension = file.toString().split("\\.")[1];
    if (extension.equals("mp4")) {
      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
      mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
      mMediaRecorder.setVideoSize(xSize, ySize);
      mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    } else if (extension.equals("3gp")) {
      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
      mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
      mMediaRecorder.setVideoSize(xSize, ySize);
      mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    } else {

      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
      mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
      mMediaRecorder.setVideoSize(xSize, ySize);
      mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
    }

    mMediaRecorder.setOutputFile(file.getAbsolutePath());
    if (milliseconds > 0) {
      mMediaRecorder.setMaxDuration(milliseconds);
    }
    FutureActivityTask<Exception> prepTask = prepare();
    mMediaRecorder.start();
    if (milliseconds > 0) {
      new CountDownLatch(1).await(milliseconds, TimeUnit.MILLISECONDS);
    }
    prepTask.finish();
  }

  @Rpc(description = "Records video (and optionally audio) from the camera and saves it to the given location. "
      + "\nDuration specifies the maximum duration of the recording session. "
      + "\nIf duration is not provided this method will return immediately and the recording will only be stopped "
      + "\nwhen recorderStop is called or when a scripts exits. "
      + "\nOtherwise it will block for the time period equal to the duration argument.")
  public void recorderCaptureVideo(@RpcParameter(name = "targetPath") String targetPath,
      @RpcParameter(name = "duration") @RpcOptional Integer duration,
      @RpcParameter(name = "recordAudio") @RpcDefault("true") Boolean recordAudio) throws Exception {
    int ms = convertSecondsToMilliseconds(duration);
    startVideoRecording(new File(targetPath), ms, recordAudio);
  }

  private void startVideoRecording(File file, int milliseconds, boolean withAudio) throws Exception {
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    if (withAudio) {
      int audioSource = MediaRecorder.AudioSource.MIC;
      try {
        Field source =
            Class.forName("android.media.MediaRecorder$AudioSource").getField("CAMCORDER");
        audioSource = source.getInt(null);
      } catch (Exception e) {
        Log.e(e);
      }
      mMediaRecorder.setAudioSource(audioSource);
      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
      mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    } else {
      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
    }
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
    mMediaRecorder.setOutputFile(file.getAbsolutePath());
    if (milliseconds > 0) {
      mMediaRecorder.setMaxDuration(milliseconds);
    }
    FutureActivityTask<Exception> prepTask = prepare();
    mMediaRecorder.start();
    if (milliseconds > 0) {
      new CountDownLatch(1).await(milliseconds, TimeUnit.MILLISECONDS);
    }
    prepTask.finish();
  }

  private void startAudioRecording(String targetPath, int source) throws IOException {
    mMediaRecorder.setAudioSource(source);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    mMediaRecorder.setOutputFile(targetPath);
    mMediaRecorder.prepare();
    mMediaRecorder.start();
  }

  @Rpc(description = "Stops a previously started recording.")
  public void recorderStop() {
    mMediaRecorder.stop();
    mMediaRecorder.reset();
  }

  @Rpc(description = "Starts the video capture application to record a video and saves it to the specified path.")
  public void startInteractiveVideoRecording(@RpcParameter(name = "path") final String path) {
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    File file = new File(path);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
    AndroidFacade facade = mManager.getReceiver(AndroidFacade.class);
    facade.startActivityForResult(intent);
  }

  @Override
  public void shutdown() {
    mMediaRecorder.release();
  }

  // TODO(damonkohler): This shares a lot of code with the CameraFacade. It's probably worth moving
  // it there.
  private FutureActivityTask<Exception> prepare() throws Exception {
    FutureActivityTask<Exception> task = new FutureActivityTask<Exception>() {
      @Override
      public void onCreate() {
        super.onCreate();
        final SurfaceView view = new SurfaceView(getActivity());
        getActivity().setContentView(view);
        getActivity().getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED);
        view.getHolder().addCallback(new Callback() {
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
          }

          @Override
          public void surfaceCreated(SurfaceHolder holder) {
            try {
              mMediaRecorder.setPreviewDisplay(view.getHolder().getSurface());
              mMediaRecorder.prepare();
              setResult(null);
            } catch (IOException e) {
              setResult(e);
            }
          }

          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
          }
        });
      }
    };

    FutureActivityTaskExecutor taskExecutor =
        ((BaseApplication) mService.getApplication()).getTaskExecutor();
    taskExecutor.execute(task);

    Exception e = task.getResult();
    if (e != null) {
      throw e;
    }
    return task;
  }

  private int convertSecondsToMilliseconds(Integer seconds) {
    if (seconds == null) {
      return 0;
    }
    return (int) (seconds * 1000L);
  }
}
