package com.reactlibrary.vishwamdkyclib.ImageAnalysis;

/*
 * Vishwam Corp CONFIDENTIAL

 * Vishwam Corp 2018
 * All Rights Reserved.

 * NOTICE:  All information contained herein is, and remains
 * the property of Vishwam Corp. The intellectual and technical concepts contained
 * herein are proprietary to Vishwam Corp
 * and are protected by trade secret or copyright law of U.S.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Vishwam Corp
 */

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import static com.reactlibrary.vishwamdkyclib.Activities.VishwamDocActivity.frontOrNot;
import static com.reactlibrary.vishwamdkyclib.Camera.CameraSource.framesAddedCount;
/**
 * This class used for aadhaarAnalysis using tensorflow lite.
 * **/
public class AadhaarAnalysis {

    public AssetManager assetManager;
    public Context context;

    public Queue<ImageObject> docBitmapQueue = new LinkedList<>();
    public ArrayList<String> docFrontResultStringArray = new ArrayList<>();
    public ArrayList<String> docBackResultStringArray = new ArrayList<>();
    public boolean okForDocTask, firstDocFrame;
    public static boolean okForDocAnalysis, readyForDocAnalysis = false, docCaptureComplete = false;
//    public static boolean canAddDocData = true;
    public Bitmap realImage, fakeImage;

    private final String DOC_MODEL_PATH = "220819.tflite";
    private final String DOC_LABEL_PATH = "220819.txt";

    private final int DOC_INPUT_SIZE = 224;

    private Classifier classifier;
    private Executor docExecutor = Executors.newSingleThreadExecutor();

//    LibUtils libUtils;

    public static int docTotalNumFrames = 0, docRealFrames = 0, docScreenFrames = 0;
    public static float realSum = 0, fakeSum = 0;
    /**
     * Constructor to initialise assetmanager and context.
     * **/
    public AadhaarAnalysis(AssetManager assetManager, Context context) {
        this.assetManager = assetManager;
        this.context = context;
//        libUtils = new LibUtils();
    }
    /**
     * This is a method initialise tensflow classifier with model stored in the assets.
     * **/
    public void initAadhaarAnalysis() {

        docExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    classifier = TensorFlowImageClassifier.create(
                            assetManager,
                            DOC_MODEL_PATH,
                            DOC_LABEL_PATH,
                            DOC_INPUT_SIZE);

                    readyForDocAnalysis = true;

                    Log.e("initImageAnalysis", "done");

                } catch (final Exception e) {
                    throw new RuntimeException("Error initializing TensorFlow!", e);
                }
            }
        });
    }
    /**
     * This is reset initial values of different variables.
     * **/
    public void setupAadhaarAnalysis(){
        docTotalNumFrames = 0;
        /*docRealFrames = 0;
        docScreenFrames = 0;
        realSum = 0;
        fakeSum = 0;*/
        realImage = null;
        fakeImage = null;
        okForDocTask = true;
        firstDocFrame = true;
        okForDocAnalysis = true;
//        canAddDocData = true;
        docFrontResultStringArray.clear();
        docBackResultStringArray.clear();
        docCaptureComplete = false;
        framesAddedCount =0 ;
    }

    public void startAadhaarAnalysis(){

        new docAsyncTask().execute();
    }
    /**
     * Method to start image analysis using async task and passing each image object in bitmapQueue obtain on camera frames.
     * Each ImageObject object is compress to create bitmap with byte array as parameter and then scaled down to 224*224 and then processed on tensorflow classifier.
     * **/
    @SuppressLint("StaticFieldLeak")
    class docAsyncTask extends android.os.AsyncTask<String, String, String> {

        @Override
        protected String doInBackground(String... strings) {

            Iterator<ImageObject> docIterator = docBitmapQueue.iterator();

            while (docIterator.hasNext()){

                if (okForDocAnalysis) {

                    ImageObject docImageObject = docBitmapQueue.remove();
                    ByteArrayOutputStream out = new ByteArrayOutputStream();

                    YuvImage image = new YuvImage(docImageObject.byteArray, docImageObject.parameters.getPreviewFormat(),
                            docImageObject.previewW, docImageObject.previewH, null);
                    int quality = 100;   // adjust this as needed

                    image.compressToJpeg(new Rect(0, 0, docImageObject.previewW, docImageObject.previewH), quality, out);
                    byte[] finalByte = out.toByteArray();
                    Bitmap finalBitmap = BitmapFactory.decodeByteArray(finalByte, 0, finalByte.length);

                    Bitmap bitmap1 = Bitmap.createScaledBitmap(finalBitmap, 224, 224, false);

                    Matrix matrix = new Matrix();
                    matrix.postRotate(docImageObject.angle);
                    Bitmap rotated = Bitmap.createBitmap(bitmap1,0,0,bitmap1.getWidth(),bitmap1.getHeight(),matrix,true);

//                    long start = System.currentTimeMillis();
                    final List<Classifier.Recognition> docResults = classifier.recognizeImage(rotated);
                    long stop = System.currentTimeMillis();
//                    Log.e("vishwamSukshiTimeDoc", String.valueOf(stop-start));
//                    Log.e("shankResult", String.valueOf(docResults));
                    if (firstDocFrame){
                        firstDocFrame = false;
                    }else {

                        String docResultsString = docResults.toString().replace(" ", "");

                        if (frontOrNot){
//                            Log.e("vishwamOBDFront", docResultsString);
                            docFrontResultStringArray.add(docResultsString);
                        }else {
//                            Log.e("vishwamOBDBack", docResultsString);
                            docBackResultStringArray.add(docResultsString);
                        }

                        docTotalNumFrames++;
                    }
                }  else {
                    docBitmapQueue.clear();
                }
            }
            return null;
        }
    }
    /**
     * Returns image analysis results.
     * **/
    public String getAadhaarIndex(){

        if (docTotalNumFrames != 0){
            String result;
            if (frontOrNot){
                 result = docFrontResultStringArray.toString().replaceAll(" ", "");
            }else {
                 result = docBackResultStringArray.toString().replaceAll(" ", "");
            }

            return result;
        }else{
            return "";
        }
    }
}