from math import sqrt

def greyscale(mat_img):
    gray_img = []
    for ligne in mat_img:
        lig = []
        for r,g,b in ligne:
            v = int(r*0.2125 + g*0.7154 + b*0.0721)
            lig.append((v,)*3)
        gray_img.append(lig)
    return gray_img

def appliquer_convolution(img, mat, i, j):
    somme = 0
    for y in range(len(mat)):
        for x in range(len(mat[0])):
            pixel_i = i - (len(mat[0]) // 2) + x
            pixel_j = j - (len(mat) // 2) + y
            pix = pixel(img, pixel_i, pixel_j)
            somme += pix[0]*mat[y][x]
    return min(max(somme,0), 255)

def convolution(mat_img, mat):
    return_img = []
    for j in range(len(mat_img)):
        ligne = []
        for i in range(len(mat_img[0])):
            val = appliquer_convolution(mat_img, mat, i, j)
            ligne.append((val,)*3)
        return_img.append(ligne)
    return return_img

def is_greyscale(img):
    _greyscale = True
    for ligne in img:
        for r,g,b in ligne:
            if not (r==g and g==b):
                _greyscale = False
                break
        if not _greyscale:
            break
    return _greyscale

def invert(img):
    result_image = []
    for ligne in img:
        result_ligne = []
        for r,g,b in ligne:
            result_ligne.append((255-r, 255-g, 255-b))
        result_image.append(result_ligne)
    return result_image

def pixel(img, i, j, default=(0,0,0)):
    #i la colone et j la ligne
    if 0 <= i < len(img[0]) and 0 <= j < len(img):
        return img[j][i]
    else:
        return default

def reduction_bruit(img, mat, i, j):
    somme = 0
    for y in range(len(mat)):
        for x in range(len(mat[0])):
            pixel_i = i - (len(mat[0]) // 2) + x
            pixel_j = j - (len(mat) // 2) + y
            pix = pixel(img, pixel_i, pixel_j)
            somme += pix[0]*mat[y][x]
    normalise = round(somme)
    return normalise

def convolution_gauss(mat_img):
    mat_gauss = [
        [2/159, 4/159, 5/159, 4/159,2/159],
        [4/159, 9/159,12/159, 9/159,4/159],
        [5/159,12/159,15/159,12/159,5/159],
        [4/159, 9/159,12/159, 9/159,4/159],
        [2/159, 4/159, 5/159, 4/159,2/159]
    ]

    return_img = []
    for j in range(len(mat_img)):
        ligne = []
        for i in range(len(mat_img[0])):
            val = reduction_bruit(mat_img, mat_gauss, i, j)
            ligne.append((val,)*3)
        return_img.append(ligne)
    return return_img

def calcul_norme(pixel1, pixel2):
    valeur = pixel1[0]**2 + pixel2[0]**2
    norm = round(sqrt(valeur))
    norm = int(min(norm, 255))
    return norm

def application_norme(im_x, im_y):
    result_image = []
    for j in range(len(im_x)):
        ligne = []
        for i in range(len(im_x[0])):
            pixel1 = im_x[j][i]
            pixel2 = im_y[j][i]
            norme = calcul_norme(pixel1, pixel2)
            ligne.append((norme,)*3)
        result_image.append(ligne)
    return result_image