package com.cordova.camera.view;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.view.Surface;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.cordova.camera.util.IDUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class CameraActivity extends Activity {
  public static final String KEY_OUTPUT_FILE_PATH = "outputFilePath";
  public static final String KEY_CONTENT_TYPE = "contentType";

  public static final String CONTENT_TYPE_ID_CARD_FRONT = "IDCardFront";

  private static final int REQUEST_CODE_PICK_IMAGE = 100;
  private static final int PERMISSIONS_REQUEST_CAMERA = 800;
  private static final int PERMISSIONS_EXTERNAL_STORAGE = 801;

  private File outputFile;
  private String contentType;
  private Handler handler = new Handler();

  private LinearLayout takePictureContainer;
  private CameraLayout confirmResultContainer;
  private ImageView cameraSwitch;
  private CameraView cameraView;
  private ImageView displayImageView;
  private ImageView takePhotoBtn;
  private PermissionCallback permissionCallback = new PermissionCallback() {
    @Override
    public boolean onRequestPermission() {
      ActivityCompat.requestPermissions(CameraActivity.this,
        new String[]{Manifest.permission.CAMERA},
        PERMISSIONS_REQUEST_CAMERA);
      return false;
    }
  };
  private CameraLayout mCameraLayout;
  private ImageView mIvLightButton;
  private boolean mIsCrop;//是否自动截图

  @Override
  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(IDUtil.getIdByNameAndType(CameraActivity.this, "layout", "activity_camera"));

    takePictureContainer = (LinearLayout) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "take_picture_container"));
    mCameraLayout = (CameraLayout) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "cameralayout"));
    mIvLightButton = (ImageView) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "iv_light_button"));
    mIvLightButton.setOnClickListener(lightButtonOnClickListener);
    confirmResultContainer = (CameraLayout) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "confirm_result_container"));

    cameraView = (CameraView) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "camera_view"));
    cameraView.getCameraControl().setPermissionCallback(permissionCallback);
    cameraSwitch = (ImageView) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "camera_switch"));
    cameraSwitch.setOnClickListener(cameraSwitchOnClickListener);
    takePhotoBtn = (ImageView) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "take_photo_button"));
    findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "album_button")).setOnClickListener(albumButtonOnClickListener);
    takePhotoBtn.setOnClickListener(takeButtonOnClickListener);

    // confirm result;
    displayImageView = (ImageView) findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "display_image_view"));
    confirmResultContainer.findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "confirm_button")).setOnClickListener(confirmButtonOnClickListener);
    confirmResultContainer.findViewById(IDUtil.getIdByNameAndType(CameraActivity.this, "id", "cancel_button")).setOnClickListener(confirmCancelButtonOnClickListener);

    setOrientation(getResources().getConfiguration());
    initParams();

    cameraView.setAutoPictureCallback(autoTakePictureCallback);
  }

  @Override
  protected void onStart() {
    super.onStart();

  }

  @Override
  protected void onStop() {
    super.onStop();

  }

  @Override
  protected void onPause() {
    super.onPause();
    cameraView.stop();
  }

  @Override
  protected void onResume() {
    super.onResume();
    cameraView.start();
  }

  private void initParams() {
    String outputPath = getIntent().getStringExtra(KEY_OUTPUT_FILE_PATH);
    if (outputPath != null) {
      outputFile = new File(outputPath);
    }
    contentType = getIntent().getStringExtra(KEY_CONTENT_TYPE);
    int maskType;
    if (contentType.equals(CONTENT_TYPE_ID_CARD_FRONT)) {
      maskType = MaskView.MASK_TYPE_ID_CARD_FRONT;

    } else {
      maskType = MaskView.MASK_TYPE_NONE;

    }
    mIsCrop = getIntent().getBooleanExtra("isCrop", true);

    cameraView.setMaskType(maskType, this);
  }

  private void showTakePicture() {
    cameraView.getCameraControl().resume();
    updateFlashMode();
    takePictureContainer.setVisibility(View.VISIBLE);
    confirmResultContainer.setVisibility(View.INVISIBLE);
  }

  private void showCrop() {
    cameraView.getCameraControl().pause();
    updateFlashMode();
    takePictureContainer.setVisibility(View.INVISIBLE);
    confirmResultContainer.setVisibility(View.INVISIBLE);
  }

  private void showResultConfirm() {
    cameraView.getCameraControl().pause();
    updateFlashMode();
    takePictureContainer.setVisibility(View.INVISIBLE);
    confirmResultContainer.setVisibility(View.VISIBLE);
  }

  // take photo;
  private void updateFlashMode() {
    int flashMode = cameraView.getCameraControl().getFlashMode();
    if (flashMode == ICameraControl.FLASH_MODE_TORCH) {
      mIvLightButton.setImageResource(IDUtil.getIdByNameAndType(CameraActivity.this, "drawable", "light_on"));
    } else {
      mIvLightButton.setImageResource(IDUtil.getIdByNameAndType(CameraActivity.this, "drawable", "light_off"));
    }
  }

  private View.OnClickListener albumButtonOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      finish();
    }
  };

  private View.OnClickListener lightButtonOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      if (cameraView.getCameraControl().getFlashMode() == ICameraControl.FLASH_MODE_OFF) {
        if (cameraView.getCameraControl().isSupportFlashMode()) {
          cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_TORCH);
        } else {
          Toast.makeText(CameraActivity.this, "当前相机不支持该闪光灯模式", Toast.LENGTH_SHORT).show();
        }

      } else {
        cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_OFF);
      }
      updateFlashMode();
    }
  };

  private View.OnClickListener cameraSwitchOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      int flashMode = cameraView.getCameraControl().getFlashMode();
      if (flashMode == ICameraControl.FLASH_MODE_TORCH) {
        mIvLightButton.setImageResource(IDUtil.getIdByNameAndType(CameraActivity.this, "drawable", "light_off"));
      }
      cameraView.switchCamera();
    }
  };

  private View.OnClickListener takeButtonOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      cameraView.takePicture(outputFile, takePictureCallback, mIsCrop);
    }
  };

  private CameraView.OnTakePictureCallback autoTakePictureCallback = new CameraView.OnTakePictureCallback() {
    @Override
    public void onPictureTaken(final Bitmap bitmap) {
      CameraThreadPool.execute(new Runnable() {
        @Override
        public void run() {
          try {
            FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
            bitmap.recycle();
            fileOutputStream.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
          Intent intent = new Intent();
          intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, contentType);
          setResult(Activity.RESULT_OK, intent);
          finish();
        }
      });
    }
  };

  private CameraView.OnTakePictureCallback takePictureCallback = new CameraView.OnTakePictureCallback() {
    @Override
    public void onPictureTaken(final Bitmap bitmap) {
      handler.post(new Runnable() {
        @Override
        public void run() {
          takePictureContainer.setVisibility(View.INVISIBLE);
          displayImageView.setImageBitmap(bitmap);
          showResultConfirm();
        }
      });
    }
  };

  private void doConfirmResult() {
    CameraThreadPool.execute(new Runnable() {
      @Override
      public void run() {
        try {
          FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
          Bitmap bitmap = ((BitmapDrawable) displayImageView.getDrawable()).getBitmap();
          bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
          fileOutputStream.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
        Intent intent = new Intent();
        intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, contentType);
        setResult(Activity.RESULT_OK, intent);
        finish();
      }
    });
  }

  private View.OnClickListener confirmButtonOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      doConfirmResult();
    }
  };

  private View.OnClickListener confirmCancelButtonOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      displayImageView.setImageBitmap(null);
      showTakePicture();
    }
  };

  private String getRealPathFromURI(Uri contentURI) {
    String result;
    Cursor cursor = null;
    try {
      cursor = getContentResolver().query(contentURI, null, null, null, null);
    } catch (Throwable e) {
      e.printStackTrace();
    }
    if (cursor == null) {
      result = contentURI.getPath();
    } else {
      cursor.moveToFirst();
      int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
      result = cursor.getString(idx);
      cursor.close();
    }
    return result;
  }

  @Override
  public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setOrientation(newConfig);
  }

  private void setOrientation(Configuration newConfig) {
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    int orientation;
    int cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT;
    switch (newConfig.orientation) {
      case Configuration.ORIENTATION_PORTRAIT:
        cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT;
        orientation = CameraLayout.ORIENTATION_PORTRAIT;
        break;
      case Configuration.ORIENTATION_LANDSCAPE:
        orientation = CameraLayout.ORIENTATION_HORIZONTAL;
        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
          cameraViewOrientation = CameraView.ORIENTATION_HORIZONTAL;
        } else {
          cameraViewOrientation = CameraView.ORIENTATION_INVERT;
        }
        break;
      default:
        orientation = CameraLayout.ORIENTATION_PORTRAIT;
        cameraView.setOrientation(CameraView.ORIENTATION_PORTRAIT);
        break;
    }
    mCameraLayout.setOrientation(orientation);
    cameraView.setOrientation(cameraViewOrientation);
    confirmResultContainer.setOrientation(orientation);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_PICK_IMAGE) {
      if (resultCode == Activity.RESULT_OK) {
        Uri uri = data.getData();
        showCrop();
      } else {
        cameraView.getCameraControl().resume();
      }
    }
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                         @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
      case PERMISSIONS_REQUEST_CAMERA: {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
          cameraView.getCameraControl().refreshPermission();
        } else {
          Toast.makeText(getApplicationContext(), "本功能需要相机权限", Toast.LENGTH_LONG)
            .show();
        }
        break;
      }
      case PERMISSIONS_EXTERNAL_STORAGE:
      default:
        break;
    }
  }

  /**
   * 做一些收尾工作
   */
  private void doClear() {
    CameraThreadPool.cancelAutoFocusTimer();
  }


  @Override
  protected void onDestroy() {
    super.onDestroy();
    this.doClear();
  }
}
