import sys
import platform
import glob
import cv2
import os
import jsonpickle
import numpy as np
import mysql.connector
from flask import Flask, request
from PIL import Image
from mysql.connector import Error
from flask_apscheduler import APScheduler
import base64
from io import BytesIO


######
import matplotlib.pyplot as plt

import math
from scipy import ndimage
#####

#print(cv2.__version__)



print(sys.version)
app = Flask(__name__)

threshold = 40
kernel = np.ones((5, 5), np.uint8)
global status
status="NOT"
global isGoodFeatures
isGoodFeatures="GOOD"
orb = cv2.ORB_create(nfeatures=2000)
descriptor = cv2.xfeatures2d.BEBLID_create(0.75)


global images
images = []
global matchlist
matchlist = []
global ClassNames
ClassNames = []
global filelist
filelist= []
global name

APP_ROOT = os.path.dirname(os.path.abspath(__file__))   # refers to application_top
APP_STATIC = os.path.join(APP_ROOT, 'arhimaya/Headerimage')
APP_STATIC_SAVEDIRECTORY = os.path.join(APP_ROOT, 'arhimaya/ProcessImages')
#print(APP_STATIC)
for root, dirs, files in os.walk(APP_STATIC):
    for file in files:
        # append the file name to the list
        filelist.append(os.path.join(root, file))
#print(filelist)

for name in filelist:
    newPath = name.replace(os.sep, '/')
    # print(newPath)
    # print(name)
    #print(newPath)
    imgCur = cv2.imread(newPath, 0)
    images.append(imgCur)
    # print(imgCur)
    ClassNames.append(os.path.splitext(newPath)[0] + os.path.splitext(newPath)[1])

#print(ClassNames)
@app.route('/VisionMaya')
def VisionMaya():
  return 'Welcome to VisionMaya 2.2 UPDATED AUTOSAVE BBLIED'

@app.route('/blogs')
def blogs():
  return 'Welcome1 to The Blog App_Updated'

@app.route('/blog/<int:id>')
def blog(id):
  return "The Blog id is {}".format(id)

@app.route('/selva')
def selva():
    global ClassNames
    classNames=["sankari","siva"]
    return jsonpickle.encode(ClassNames)





@app.route('/siva')
def siva():
    global filelist
    global name
    global images
    global ClassNames
    global matchlist
    
    filelist.clear()
    ClassNames.clear()
    filelist.clear()
    images.clear()
    matchlist.clear()

    #filelist = []
    #print(files)
    APP_ROOT = os.path.dirname(os.path.abspath(__file__))   # refers to application_top
    APP_STATIC = os.path.join(APP_ROOT, 'arhimaya/Headerimage')
    
    #for files in os.walk('APP_STATIC'):
        #for filename in files:
            #fname = os.path.join(dirpath, filename)
            #if fname.endswith('.jpg'):
                #print(fname)
    for root, dirs, files in os.walk(APP_STATIC):
        for file in files:
            # append the file name to the list
            filelist.append(os.path.join(root, file))
    #print(filelist)

    for name in filelist:
        newPath = name.replace(os.sep, '/')
        # print(newPath)
        # print(name)
        #print(newPath)
        imgCur = cv2.imread(newPath, 0)
        images.append(imgCur)
        # print(imgCur)
        ClassNames.append(os.path.splitext(newPath)[0] + os.path.splitext(newPath)[1])

    #siva="SANKARI"
    #for dirpath, dirs, files in os.walk('env'):
      #for filename in files:
        #fname = os.path.join(dirpath,filename)
        #siva=siva+'.'+fname
        #if fname.endswith('.py'):
          #print(fname)
          #siva=siva+"New"+fname
    return jsonpickle.encode(ClassNames)

#print(ClassNames)
def findDes(images):
    desList = []
    for img in images:
        #kp, des = orb.detectAndCompute(img, None)
        kp = orb.detect(img, None)
        kp, des = descriptor.compute(img, kp)
        desList.append(des)
    return desList


def findID(img, deslist):
    kp2 = orb.detect(img, None)
    kp2, des2 = descriptor.compute(img, kp2)
    #kp2, des2 = orb.detectAndCompute(img, None)
    #bf = cv2.BFMatcher()
    bf = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING)
    matchlist.clear()
    finalvalue = -1
    try:
        for des in deslist:
            matches = bf.knnMatch(des, des2, k=2)
            good = []
            matched1 = []
            matched2 = []
            nn_match_ratio = 0.8  # Nearest neighbor matching ratio
            
            for m, n in matches:
                if m.distance < nn_match_ratio * n.distance:
                #if n < len(matches) - 1 and n.distance < 0.7 * matches[n+1].distance:
                    good.append(des[m.queryIdx])
                    #matched1.append(kpts1[m.queryIdx])
                    #matched2.append(kpts2[m.trainIdx])
                    #print(len(matched1))
                    
            matchlist.append(len(good))
            
    except:
        pass
    if len(matchlist) != 0:
        if max(matchlist) > threshold:
            finalvalue = matchlist.index(max(matchlist))
    return finalvalue


@app.route('/')
def hello_world():
    return cv2.__version__

def variance_of_laplacian(image):
	# compute the Laplacian of the image and then return the focus
	# measure, which is simply the variance of the Laplacian
	return cv2.Laplacian(image, cv2.CV_64F).var()

@app.route('/post_json', methods=['POST'])
def image_check():
    # ----- SECTION 1 -----
    # File naming process for nameless base64 data.
    # We are using the timestamp as a file_name.
    from datetime import datetime
    dateTimeObj = datetime.now()
    file_name_for_base64_data = dateTimeObj.strftime("%d-%b-%Y--(%H-%M-%S)")

    content_type = request.headers.get('Content-Type')
    if (content_type == 'application/json'):
        json = request.json
        #return json['firstName']
    else:
        return 'Content-Type not supported!'
    
    # ----- SECTION 2 -----
    try:
        #status=json['lastname']
        
        decoded_img = base64.b64decode(json['firstName'])
        img = Image.open(BytesIO(decoded_img))
        np_data = np.frombuffer(decoded_img,np.uint8)
        img21 = cv2.imdecode(np_data,cv2.IMREAD_UNCHANGED)
        #file_name = APP_STATIC_SAVEDIRECTORY+"/"+file_name_for_base64_data + ".jpg"
        #print(file_name)
        #img.save(file_name, "jpeg")
        #print(file_name+"sss")
        ###############NEW START
        image=img21
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        fm = variance_of_laplacian(gray)
        text = "Not Blurry"
        # if the focus measure is less than the supplied threshold,
        # then the image should be considered "blurry"
        if fm < 5.0:
            text = "Blurry"
            print(text)
            isGoodFeatures="FALSE"
            

        else:
            
            orb1 = cv2.ORB_create()
                # find the keypoints with ORB
            kp = orb1.detect(image,None)
            # compute the descriptors with ORB
            kp, des = orb.compute(image, kp)
            # draw only keypoints location,not size and orientation
            #img2 = cv.drawKeypoints(foreground, kp, None, color=(0,255,0), flags=0)
            if len(kp)>400:
                print(len(kp))
                img2=image
                isGoodFeatures="GOOD"
                #cv2.imwrite('foreground.jpg', img2)
            else:
                isGoodFeatures="FALSE"
            

        ###############NEW END
        

        

        if isGoodFeatures!="FALSE":
            desList = findDes(images)
            #print(len(desList))
            #img2 = cv2.imread("test/Suresh.jpg")  # Reading the image. Change the name according to your img name

            imgOriginal = img2.copy()
            img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
            img_blur = cv2.GaussianBlur(img2, (7, 7), 1)  # Making the image blurry
            img_edges = cv2.Canny(img_blur, 30, 30)  # Finding the edges in the image for detecting where the image is.
            img_dialation = cv2.dilate(img_edges, kernel,
                                       iterations=1)  # Dilating our image so that the edges detected by canny edge detector can be made thick.
            contours, hierarchy = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)  # Detecting the contours(shapes)
            for cnt in contours:
                area = cv2.contourArea(cnt)  # checking the area of contours
                if area > 5000:  # there can be many countours so we are filtering it as our money area is large
                    peri = cv2.arcLength(cnt, True)  # Calculating our countour perimeter
                    approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)  # performimg an approximation of a shape of a contour.
                    x, y, w, h = cv2.boundingRect(approx)  # finding the x, y coordinates and height and width of our money
                    final_img = imgOriginal[y: y + h, x: x + w]  # Croping our image to get money only

                else:
                    final_img = img2  # returning our img2 image if the money is not detected and this situation comes when your image contains only money i.e. their is no any background.



            X = findID(final_img, desList)
            print(matchlist)
            #print(len(matched1))
            #print(ClassNames)
            if X != -1:
                #status = "Image has been succesfully sent to the server."+ClassNames[X]
                addurlParent=ClassNames[X]
                print(addurlParent)
                #status=ClassNames[X]+jsonpickle.encode(matchlist)
                
                connection = mysql.connector.connect(host='localhost',
                                                     database='arhimaya',
                                                     user='root',
                                                     password='Vision@3')
                sql_select_Query = "select * from others"
                # MySQLCursorDict creates a cursor that returns rows as dictionaries
                cursor = connection.cursor(dictionary=True)
                cursor.execute(sql_select_Query)
                records = cursor.fetchall()
                
                #print("Fetching each row using column name")
                for row in records:
                    id = row["targetimagepath"]
                    #print(id)
                    #print(addurlParent)
                    #name = row["Name"]
                    #price = row["Price"]
                    if addurlParent == id:
                        
                        targetContent= row["targetcontent"]
                        status = targetContent
                        #print(status+"Finished")
                        break
                    
                        #print(addurlParent+"DONE")
                    
                    #purchase_date = row["Purchase_date"]
                        

                    
               
                if connection.is_connected():
                    connection.close()
                    cursor.close()
                        #print("MySQL connection is closed")
                #cv2.putText(imgOriginal, ClassNames[X], (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0, 0, 255), 3)
                #print(status)
                
            else:
                status="WRONG"
        else:
            status="WRONG"
            

        # ----- SECTION 3 -----
        
    except Exception as e:
        status = "Error! = " + str(e)
    
    return status


if __name__ == '__main__':
    #app.run(host="192.168.1.7", port=5000)
    app.run()

