import cv2
import numpy as np
from pyzbar import pyzbar
from urllib.request import Request, urlopen
from pyzbar.pyzbar import ZBarSymbol


def detetcting(arr):

    frame2 = cv2.imdecode(np.array(bytearray(arr), dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
    frame = cv2.imdecode(np.array(bytearray(arr), dtype=np.uint8), cv2.IMREAD_COLOR)

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 51, 9)

    # Fill rectangular contours
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
        cv2.drawContours(thresh, [c], -1, (255, 255, 255), -1)

    # Morph open
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9))
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=4)

    # Draw rectangles
    cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    for c in cnts:
        x, y, w, h = cv2.boundingRect(c)
        if (w > h):
            scale = 200 / w
            if (w / h < 3 or w / h > 6) :
                continue
        else:
            scale = 200 / h
            if (h / w < 3 or h / w > 6) :
                continue
        y = int(y*scale) + 5
        x = int(x*scale) + 5
        w = int(w*scale) - 10
        h = int(h*scale) - 10
        width = int(frame2.shape[1] * scale)
        height = int(frame2.shape[0] * scale)
        frame = cv2.resize(frame2, (width, height))
        frame = frame[y:(y + h), x:(x + w)]
        detections = pyzbar.decode(frame, symbols=[ZBarSymbol.CODE128])
        if(detections) :
            return detections[0]
#         scale = 1
#         width = int(frame.shape[1] * scale)
#         height = int(frame.shape[0] * scale)
#         frame = cv2.resize(frame, (width, height))
#
#         # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#         _, thresh = cv2.threshold(frame, 120, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
#
#         kernel = np.ones((3, 3), np.uint8)
#         thresh = cv2.dilate(thresh, kernel, iterations=1)
#         contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
#
#         bboxes = []
#         for cnt in contours:
#             area = cv2.contourArea(cnt)
#             xmin, ymin, width, height = cv2.boundingRect(cnt)
#             extent = area / (width * height)
#
#             # filter non-rectangular objects and small objects
#             if (extent > np.pi / 4) and (area > 100):
#                 bboxes.append((xmin, ymin, xmin + width, ymin + height))
#
#         qrs = []
#         info = set()
#         for xmin, ymin, xmax, ymax in bboxes:
#             roi = frame[ymin:ymax, xmin:xmax]
#
#             if ((xmax - xmin) / (ymax - ymin) < 2 and (xmax - xmin) / (ymax - ymin) > 0.5):
#                 continue
#
#             detections = pyzbar.decode(roi)
#             for barcode in detections:
#                 # print(detections)
#                 # bounding box coordinates
#                 return barcode
#                 break
#                 x, y, w, h = barcode.rect
#                 qrs.append((xmin + x, ymin + y, xmin + x + w, ymin + y + height))





    # req = Request(
    #     imageUrl,
    #     headers={'User-Agent': 'Mozilla/5.0'})
    # arr = urlopen(req).read()
    # # utils.getROI(inOMR, 'filename.jpg', noCropping=args["noCropping"])
    #
    # frame = cv2.imdecode(np.array(bytearray(arr), dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
    # frame = cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE)

#     scale = 1
#     width = int(frame.shape[1] * scale)
#     height = int(frame.shape[0] * scale)
#     frame = cv2.resize(frame, (width, height))
#
#     # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#     _, thresh = cv2.threshold(frame, 120, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
#
#     kernel = np.ones((3, 3), np.uint8)
#     thresh = cv2.dilate(thresh, kernel, iterations=1)
#     contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
#
#     bboxes = []
#     for cnt in contours:
#         area = cv2.contourArea(cnt)
#         xmin, ymin, width, height = cv2.boundingRect(cnt)
#         extent = area / (width * height)
#
#         # filter non-rectangular objects and small objects
#         if (extent > np.pi / 4) and (area > 100):
#             bboxes.append((xmin, ymin, xmin + width, ymin + height))
#
#
#     qrs = []
#     info = set()
#     for xmin, ymin, xmax, ymax in bboxes:
#       roi = frame[ymin:ymax, xmin:xmax]
#       if((xmax-xmin)/(ymax-ymin) < 2 and (xmax-xmin)/(ymax-ymin) > 0.5) :
#           continue
#       detections = pyzbar.decode(roi)
#       for barcode in detections:
#             # print(detections)
#             # imgplot = plt.imshow(roi)
#             # plt.show()
#             # info.add()
#             # bounding box coordinates
#             return barcode;
#             break
#             x, y, w, h = barcode.rect
#             qrs.append((xmin + x, ymin + y, xmin + x + w, ymin + y + height))


# barcodes = pyzbar.decode(frame)
# print(repr(barcodes))
# for barcode in barcodes:
#     x, y, w, h = barcode.rect  # 1
#     barcode_info = barcode.data.decode('utf-8')
#     cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
#
#     # 2
#     font = cv2.FONT_HERSHEY_DUPLEX
#     cv2.putText(frame, barcode_info, (x + 6, y - 6), font, 2.0, (255, 255, 255), 1)  # 3
#     with open("barcode_result.txt", mode='w') as file:
#         file.write("Recognized Barcode:" + barcode_info)
#         cv2.imshow('Barcode/QR code reader', frame)
#


# print(repr(detetcting('https://hedayatmizan.ir/sss.jpg')))