import os
from flask import Flask, flash, request, redirect, url_for, render_template, send_from_directory

from werkzeug.utils import secure_filename

from PIL import Image
import pytesseract
import cv2
import numpy as np
from pytesseract import Output

import numpy as np

from pathlib import Path

from pdf2image import convert_from_path

from scipy.ndimage import interpolation as inter

def correct_skew(image, delta=1, limit=5):
    def determine_score(arr, angle):
        data = inter.rotate(arr, angle, reshape=False, order=0)
        histogram = np.sum(data, axis=1, dtype=float)
        score = np.sum((histogram[1:] - histogram[:-1]) ** 2, dtype=float)
        return histogram, score

    if len(image.shape)==3:
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    else:
        gray = image
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] 

    scores = []
    angles = np.arange(-limit, limit + delta, delta)
    for angle in angles:
        histogram, score = determine_score(thresh, angle)
        scores.append(score)

    best_angle = angles[scores.index(max(scores))]

    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
    corrected = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, \
            borderMode=cv2.BORDER_REPLICATE)

    return best_angle, corrected

app = Flask(__name__)

UPLOAD_FOLDER = 'files/upload/'
OUTPUT_FOLDER = 'files/download/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'bmp', 'webp', 'pdf'}

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def isPDF(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in {'pdf'}

@app.route('/', methods=['GET', 'POST'])
def index():
    cwd = os.getcwd()
    fd = os.path.join(cwd , 'files/download')
    print(fd)
    if(os.path.isdir(fd)==False):
        os.mkdir(fd)

    fu = os.path.join(cwd , 'files/upload')
    if(os.path.isdir(fu)==False):
        os.mkdir(fu)  

    if request.method == 'GET':
            return render_template('index.html', files=os.listdir(fd))
    else:
        return render_template('index.html', files=os.listdir(fu))



@app.route('/download/<filename>')
def download_file(filename):
    return send_from_directory(OUTPUT_FOLDER, filename, as_attachment=True)

@app.route('/delete/<filename>')
def delete_file(filename):
    try:
        os.remove(OUTPUT_FOLDER + filename)
        return render_template('index.html', files=os.listdir(OUTPUT_FOLDER))
    except:
        flash('There was a problem deleting that file')
        return redirect(request.url)

@app.route('/transform', methods=['POST'])
def transformFile():
    if 'file' not in request.files:
        flash('No file part', 'error')
        return redirect(request.url)

    file = request.files['file']

    if file.filename == '':
        flash('No selected file')
        return redirect(request.url)

    if allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        #file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        f = os.path.join(UPLOAD_FOLDER , filename)
        # checking if it is a file
        if isPDF(filename):
            print("je to pdf")
            image = convert_from_path(f)[0]
        else:
            image = Image.open(f)

        #preprocess to improve quality of results

        image_np = np.array(image)
        clahe = cv2.createCLAHE(clipLimit=1)

        angle, rot_img = correct_skew(image_np)


        if len(rot_img.shape)==3:
            image_bw_rot = cv2.cvtColor(rot_img, cv2.COLOR_BGR2GRAY)
            final_img_rot = clahe.apply(image_bw_rot) + 5
        else:
            final_img_rot = clahe.apply(rot_img) + 5
        
       # kernel = np.ones((1, 1), np.uint8)
       # image_np = cv2.dilate(image_np, kernel, iterations=1)
        #image_np = cv2.erode(image_np, kernel, iterations=1)

        #cv2.threshold(cv2.GaussianBlur(image_np, (5, 5), 0), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

        #cv2.threshold(cv2.bilateralFilter(image_np, 5, 75, 75), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

        #cv2.threshold(cv2.medianBlur(image_np, 3), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

        #cv2.adaptiveThreshold(cv2.GaussianBlur(image_np, (5, 5), 0), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)

       # cv2.adaptiveThreshold(cv2.bilateralFilter(image_np, 9, 75, 75), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)

        #cv2.adaptiveThreshold(cv2.medianBlur(image_np, 3), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)

        custom_config = r'-l ces --oem 1 --psm 6' 
        text = pytesseract.image_to_string(image,config=custom_config)

        text_opraveno = pytesseract.image_to_string(final_img_rot,config=custom_config)

        text2 = text.encode(encoding = 'UTF-8', errors = 'strict')
        #print(text)

        fout = os.path.join(OUTPUT_FOLDER , Path(filename).stem) + ".txt"
        #print(fout)
        #fout = os.path.join(fout , ".txt")
       # os.makedirs(os.path.dirname(OUTPUT_FOLDER), exist_ok=True)
        #with open(fout, "w") as f:
         #   f.write(text)

        os.remove(os.path.join(UPLOAD_FOLDER , filename))
        return render_template('output.html', text=text, text2=text2, text_opraveno=text_opraveno)
    else:
        flash('Not suported file format')
        return redirect(request.url)
    

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