# -*- coding: utf-8 -*-

# Import required library

from __future__ import division, print_function
# coding=utf-8
import base64
import io
import json
import sys
import os
import glob
import re
import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.patches as patches

# Keras
from PIL import Image
from tensorflow.keras.applications.imagenet_utils import preprocess_input, decode_predictions
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image

# Flask utils
from flask import Flask, redirect, url_for, request, render_template
from werkzeug.utils import secure_filename
from gevent.pywsgi import WSGIServer

# Define a flask app
# app = Flask(__name__)
app = Flask(__name__)

# Model saved with Keras model.save()

dependencies = {
    'IoU': ''
}

# Add model path
# mobilenet model accuracy 80% to 85% in between
# MODEL_PATH = 'my_model_23_03.h5'
# MODEL_PATH = 'my_model_22_03_1.h5'
MODEL_PATH = 'model.h5'

# Load your trained model
# model = load_model(MODEL_PATH)
# model = load_model(MODEL_PATH, custom_objects=dependencies)


# model._make_predict_function()          # Necessary


def model_predict_car(img_path, model):
    # print('in function predict car  ',selected_model.sel_model)
    #
    # if(selected_model.sel_model=='Mobilenet'):
    #     print('if Mobilenet')
    # elif(selected_model.sel_model=='Resnet 50'):
    #     print('else Resnet 50')
    # elif(selected_model.sel_model=='VGG16'):
    #     print('else VGG16')

    filename = img_path
    image_size = 128
    unscaled = cv2.imread(filename)
    # print(unscaled)

    image_height, image_width, _ = unscaled.shape
    image = cv2.resize(unscaled, (image_size, image_size))  # Rescaled image to run the network
    feat_scaled = preprocess_input(np.array(image, dtype=np.float32))

    region = model.predict(x=np.array([feat_scaled]))[0]  # Predict the BBox

    print('region ', region)

    x0 = int(region[0] * image_width / image_size)  # Scale the BBox
    y0 = int(region[1] * image_height / image_size)

    x1 = int((region[0] + region[2]) * image_width / image_size)
    y1 = int((region[1] + region[3]) * image_height / image_size)

    # Create figure and axes
    fig, ax = plt.subplots(1)

    # Display the image
    ax.imshow(unscaled)

    # Create a Rectangle patch
    rect = patches.Rectangle((x0, y0), x1 - x0, y1 - y0, linewidth=2, edgecolor='r', facecolor='none')

    # Add the patch to the Axes
    ax.add_patch(rect)

    plt.show()


def model_predict_car_new(img_path, model):
    filename = img_path
    image_size = 128
    unscaled = cv2.imread(filename)
    # print(unscaled)

    # print('filename ', filename)
    # plt.imshow(cv2.imread(filename))
    # plt.imshow(unscaled)

    image_height, image_width, _ = unscaled.shape
    image = cv2.resize(unscaled, (image_size, image_size))  # Rescaled image to run the network

    feat_scaled = preprocess_input(np.array(image, dtype=np.float32))

    region_1 = model.predict(x=np.array([feat_scaled]))  # Predict the BBox
    print(region_1)
    region=region_1[0]
    print('region ', region)

    x0 = int(region[0] * image_width / image_size)  # Scale the BBox
    y0 = int(region[1] * image_height / image_size)

    x1 = int((region[0] + region[2]) * image_width / image_size)
    y1 = int((region[1] + region[3]) * image_height / image_size)

    # Blue color in BGR
    color = (255, 0, 0)

    # Line thickness of 2 px
    thickness = 2

    # cv2.rectangle(unscaled, (x0, y0), (x1 + x0, y1 + y0),color,thickness)
    cv2.rectangle(unscaled, (x0, y0), (x1, y1), color, thickness)

    # # Create figure and axes
    # fig, ax = plt.subplots(1)
    #
    # # Display the image
    # ax.imshow(unscaled)
    #
    # # # Create a Rectangle patch
    # # rect = patches.Rectangle((x0, y0), x1 - x0, y1 - y0, linewidth=2, edgecolor='r', facecolor='none')
    # #
    # # # Add the patch to the Axes
    # # ax.add_patch(rect)
    # #
    # plt.show()

    return unscaled


@app.route('/', methods=['GET'])
def index():
    # Main page
    return render_template('home.html')

@app.route('/home', methods=['GET'])
def home():    # Main page
    return render_template('home.html')

@app.route('/selected_model', methods=['POST'])
def selected_model():
    selected_model.sel_model = request.form['sel_model'];
    print('_sel_model ', selected_model.sel_model)
    return json.dumps({'status': 'OK', 'selected_model': selected_model.sel_model});


from PIL import Image as im


@app.route('/predict', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        # Get the file from post request
        f = request.files['file']

        # Save the file to ./uploads
        basepath = os.path.dirname(__file__)
        file_path = os.path.join(
            basepath, 'uploads', secure_filename(f.filename))
        f.save(file_path)

        # Make prediction
        # preds = model_predict_car(file_path, model)
        preds = model_predict_car_new(file_path, model)

        print(preds.shape)
        # print()
        print('Predict image')

        # print(preds)
        # Process your result for human
        ## pred_class = preds.argmax(axis=-1)            # Simple argmax
        # pred_class = decode_predictions(preds, top=1)   # ImageNet Decode
        # result = str(pred_class[0][0][1])               # Convert to string
        # return result

        data = im.fromarray(preds)

        print('file name ' + f.filename)

        # Delete old file
        files = glob.glob('static/save_img/*')
        for f1 in files:
            os.remove(f1)

        # files = glob.glob('images/*')
        # for f1 in files:
        #     os.remove(f1)

        k = f.filename.rfind(".")

        # printing the filename
        file_name=f.filename[:k];
        print('f.filename ' +f.filename[:k])
        # print('k ' +k)

        # saving the final output
        # as a PNG file
        a = 'static/save_img/'
        b = file_name
        c = '.png'
        file_p = a + b + c
        data.save(file_p)

        # np_img = Image.fromarray(preds)
        # print('from array',np_img)
        # img_encoded = image_to_byte_array(np_img)
        # print('Encode image',img_encoded)
        # base64_bytes = base64.b64encode(img_encoded).decode("utf-8")
        # # return jsonify({'status': True, 'image': image})

        print('return image')
        return render_template('show_image.html', user_image=file_p)
    # return None


if __name__ == '__main__':
    app.run(debug=True)
