package com.daasuu.sample;

import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.Size;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.daasuu.mp4compose.FillMode;
import com.daasuu.mp4compose.FillModeCustomItem;
import com.daasuu.mp4compose.composer.Mp4Composer;
import com.daasuu.mp4compose.filter.GlFilter;
import com.daasuu.sample.widget.GesturePlayerTextureView;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FillModeCustomActivity extends AppCompatActivity {

    private final static String PATH_ARG = "PATH_ARG";
    private static final String TAG = "SAMPLE";

    private String srcPath;
    private float baseWidthSize;
    private GesturePlayerTextureView playerTextureView;
    private Button btnRotate;
    private Button btnCodec;
    private Button btnClose;
    private Button btnStartPlayMovie;
    private Button btnColorChange;
    private RelativeLayout layoutCodec;
    private FrameLayout layoutCropChange;
    private AlertDialog clearColorDialog;
    private SceneCropColor sceneCropColor = SceneCropColor.BLACK;

    public static void startActivity(Context context, String path) {
        Intent intent = new Intent(context, FillModeCustomActivity.class);
        intent.putExtra(PATH_ARG, path);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fill_mode_custom);

        if (getIntent() == null || getIntent().getStringExtra(PATH_ARG) == null) {
            finish();
            return;
        }
        srcPath = getIntent().getStringExtra(PATH_ARG);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        btnRotate = findViewById(R.id.btn_rotate);
        btnRotate.setOnClickListener((v) -> {
            playerTextureView.updateRotate();
        });
        btnCodec = findViewById(R.id.btn_codec);
        btnCodec.setOnClickListener((v) -> {
            codec();
        });
        layoutCodec = findViewById(R.id.layout_codec);
        btnClose = findViewById(R.id.close);
        btnStartPlayMovie = findViewById(R.id.start_play_movie);

        btnColorChange = findViewById(R.id.btn_color_change);
        layoutCropChange = findViewById(R.id.layout_crop_change);
        btnColorChange.setOnClickListener((v) -> {
            if (clearColorDialog == null) {

                AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
                builder.setTitle("Choose a background color");
                builder.setOnDismissListener(dialog -> {
                    clearColorDialog = null;
                });

                final SceneCropColor[] items = SceneCropColor.values();
                CharSequence[] charList = new CharSequence[items.length];
                for (int i = 0, n = items.length; i < n; i++) {
                    charList[i] = items[i].name();
                }
                builder.setItems(charList, (dialog, item) -> {
                    sceneCropColor = items[item];
                    layoutCropChange.setBackgroundColor(ContextCompat.getColor(FillModeCustomActivity.this, sceneCropColor.getColorRes()));
                });
                clearColorDialog = builder.show();
            } else {
                clearColorDialog.dismiss();
            }
        });

        initPlayer();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (playerTextureView != null) {
            playerTextureView.play();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (playerTextureView != null) {
            playerTextureView.pause();
        }
    }

    private void initPlayer() {
        FrameLayout frameLayout = findViewById(R.id.layout_crop_change);
        playerTextureView = new GesturePlayerTextureView(getApplicationContext(), srcPath);

        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
        layoutParams.gravity = Gravity.CENTER;

        playerTextureView.setLayoutParams(layoutParams);
        baseWidthSize = (getWindowHeight(this) - dp2px(192, this)) / 16f * 9;
        playerTextureView.setBaseWidthSize(baseWidthSize);

        frameLayout.addView(playerTextureView, 1);
    }

    private void codec() {

        layoutCodec.setVisibility(View.VISIBLE);
        btnCodec.setEnabled(false);
        btnRotate.setEnabled(false);
        btnColorChange.setEnabled(false);
        final ProgressBar progressBar = findViewById(R.id.progress_bar);
        progressBar.setMax(100);

        Size resolution = getVideoResolution(srcPath);

        FillModeCustomItem fillModeCustomItem = new FillModeCustomItem(
                playerTextureView.getScaleX(),
                playerTextureView.getRotation(),
                playerTextureView.getTranslationX() / baseWidthSize * 2f,
                playerTextureView.getTranslationY() / (baseWidthSize / 9f * 16) * 2f,
                resolution.getWidth(),
                resolution.getHeight()
        );

        final String videoPath = getVideoFilePath();
        btnStartPlayMovie.setEnabled(false);
        btnStartPlayMovie.setOnClickListener((v) -> {
            Uri uri = Uri.parse(videoPath);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            intent.setDataAndType(uri, "video/mp4");
            startActivity(intent);
        });
        GlFilter glFilter = new GlFilter();
        ClearColorItem clearColorItem = sceneCropColor.getClearColorItem();
        glFilter.setClearColor(clearColorItem.getRed(), clearColorItem.getGreen(), clearColorItem.getBlue(), clearColorItem.getAlpha());

        new Mp4Composer(srcPath, videoPath)
                .size(720, 1280)
                .filter(glFilter)
                .fillMode(FillMode.CUSTOM)
                .customFillMode(fillModeCustomItem)
                .listener(new Mp4Composer.Listener() {
                    @Override
                    public void onProgress(double progress) {
                        Log.d(TAG, "onProgress = " + progress);
                        runOnUiThread(() -> progressBar.setProgress((int) (progress * 100)));
                    }

                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "onCompleted()");
                        exportMp4ToGallery(getApplicationContext(), videoPath);
                        runOnUiThread(() -> {
                            progressBar.setProgress(100);

                            btnStartPlayMovie.setEnabled(true);
                            btnClose.setVisibility(View.VISIBLE);
                            btnClose.setOnClickListener((v) -> {
                                layoutCodec.setVisibility(View.GONE);
                                btnCodec.setEnabled(true);
                                btnRotate.setEnabled(true);
                                btnColorChange.setEnabled(true);
                            });
                            Toast.makeText(FillModeCustomActivity.this, "codec complete path =" + videoPath, Toast.LENGTH_SHORT).show();
                        });
                    }

                    @Override
                    public void onCanceled() {

                    }

                    @Override
                    public void onFailed(Exception exception) {
                        Log.d(TAG, "onFailed()");
                    }
                })
                .start();

    }


    public static int getWindowHeight(Context context) {
        Display disp = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        Point size = new Point();
        disp.getSize(size);
        return size.y;
    }

    public static int dp2px(float dpValue, final Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    public File getAndroidMoviesFolder() {
        return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
    }

    public String getVideoFilePath() {
        return getAndroidMoviesFolder().getAbsolutePath() + "/" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date()) + ".mp4";
    }

    public Size getVideoResolution(String path) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        retriever.setDataSource(path);
        int width = Integer.valueOf(
                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)
        );
        int height = Integer.valueOf(
                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)
        );
        retriever.release();
        int rotation = getVideoRotation(path);
        if (rotation == 90 || rotation == 270) {
            return new Size(height, width);
        }
        return new Size(width, height);
    }


    public int getVideoRotation(String videoFilePath) {
        MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
        mediaMetadataRetriever.setDataSource(videoFilePath);
        String orientation = mediaMetadataRetriever.extractMetadata(
                MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION
        );
        return Integer.valueOf(orientation);
    }

    public static void exportMp4ToGallery(Context context, String filePath) {
        final ContentValues values = new ContentValues(2);
        values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
        values.put(MediaStore.Video.Media.DATA, filePath);
        context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                values);
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                Uri.parse("file://" + filePath)));
    }
}