package com.videonext;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.view.View;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MediaPlayer {
    static {
        System.loadLibrary("VNMediaClient-jni");
    }

    public enum ScaleMode {FillStretch, FillProportional, OriginalSize}

    private long playerId = 0;
    private String resultMsg = "";
    private int resultCode = 0;
    private int[] imgBuf = null;
    private View contentView = null;
    private int width = 0;
    private int height = 0;
    private int timeSecond;
    private int timeUSecond;
    private Lock imageMutex = new ReentrantLock(true);

    public MediaPlayer(View view) {
        contentView = view;
        this.width = 0;
        this.height = 0;
    }

    public void open(String url) {
        playerId = nativeOpen(url);

        if (playerId == 0) {
            // Oops. something went wrong..
        }
    }

    public void play() {
        if (playerId != 0)
            nativePlay(playerId);
    }

    public void stop() {
        if (playerId != 0) {
            nativeStop(playerId);
            playerId = 0;
        }
    }

    public void pause() {
        if (playerId != 0)
            nativePause(playerId);
    }

    public void jump(int timestamp) {
        if (playerId != 0)
            nativeJump(playerId, timestamp);
    }

    public long getTimeSecond() {
        return this.timeSecond;
    }

    public long getTimeUSecond() {
        return this.timeUSecond;
    }

    private int[] allocImageBuf(int width, int height) {
        this.width = width;
        this.height = height;

        imgBuf = new int[width * height];
        return imgBuf;
    }

    private void onStateChanged(int state, int resultCode, String resultString) {
        if(state == 6)
            nativePlay(playerId);
    }

    private void lockImageBuffer()
    {
        imageMutex.lock();
    }

    private void unlockImageBuffer()
    {
        imageMutex.unlock();
    }

    private void onNewVideoFrame(/*int frame[],
                                 int width, int height,
                                 byte objsData[],*/
                                 int timeSec,
                                 int timeUSec) {

        contentView.postInvalidate();
        this.timeSecond = timeSec;
        this.timeUSecond = timeUSec;
    }


    private Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {

        int width = bm.getWidth();
        int height = bm.getHeight();

        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;

        // create a matrix for the manipulation
        Matrix matrix = new Matrix();

        // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight);

        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);

        return resizedBitmap;
    }

    private Bitmap resizeImage(Bitmap bm, int maxHeight, int maxWidth) {
        return resizeImage(bm, maxHeight, maxWidth, ScaleMode.FillStretch);
    }

    public void paint(Canvas canvas, int headerHeight, int screenWidth, int screenHeight) {
        if (imgBuf == null)
            return;
        Bitmap origImg = Bitmap.createBitmap(imgBuf, 0, width, width, height, Bitmap.Config.RGB_565);
        Bitmap newBitmap = resizeImage(origImg, canvas.getHeight() - headerHeight, canvas.getWidth(), ScaleMode.FillProportional);

        canvas.drawBitmap(newBitmap, (screenWidth - newBitmap.getWidth()) / 2, 0, null);
    }

    private Bitmap resizeImage(Bitmap bm, int maxHeight, int maxWidth, ScaleMode mode) {
        int newImgHeight = bm.getHeight();
        int newImgWidth = bm.getWidth();

        switch (mode) {
            case FillStretch:
                newImgHeight = maxHeight;
                newImgWidth = maxWidth;
                break;
            case FillProportional:
                float ratio = Math.min(
                        (float) maxWidth / bm.getWidth(),
                        (float) maxHeight / bm.getHeight()
                );
                newImgWidth = Math.round(ratio * bm.getWidth());
                newImgHeight = Math.round(ratio * bm.getHeight());
                break;
            case OriginalSize:
                // use defaults of original image size => no resizing
            default:
                // use defaults of original image size => no resizing
        }
        return getResizedBitmap(bm, newImgHeight, newImgWidth);
    }

    private native long nativeOpen(String url);
    private native void nativePlay(long playerId);
    private native void nativeStop(long playerId);
    private native void nativePause(long playerId);
    private native void nativeJump(long playerId, int timestamp);
    private native void nativeResume(long playerId, int direction);
}
