#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Blue Fibrosis Analysis

This file contains the body of loading analyzing and saving the images
for the specific algorithms see fibrosis_analysis.py and settings.py
"""

import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import filedialog
import numpy as np
from skimage import io, color, img_as_float, img_as_uint
from PIL import Image

from . import settings
from .settings import createColorMasks
from .fibrosis_segmentation import findBlueAndRed, findWhite

#covers everything not selected by the mask and plots it
def showMask(im,mask,name):
    plt.title(name)
    plt.axis('off')
    plt.imshow(coverUnMasked(im,mask))

#covers everything not selected by the mask
def coverUnMasked(im,mask):
    im_copy = img_as_uint(im)
    im_copy[np.logical_not(mask),:] = 0
    return im_copy

#increases the saturation to 100% for everything selected by the mask
def beautify(colorMask, HSV):
    im_copy = HSV.copy()
    im_copy[colorMask,1] = 255
    return im_copy

#dummy class to have the data dynamically assigned to it
class Data(object):
    pass

#prints the summary text from the analysis of one file
def printTextOne(filename, data):
    print(filename)
    print('Pixels counts:')
    print('\tPass 1: Red: {red1}, Blue: {blue1}, White: {white1}, Other: {other1}'.format(**data.colorCounts))
    print('\tFinal: Red: {red2}, Blue: {blue2}, White: {white2}, Other: {other2}'.format(**data.colorCounts))
    print('The percent fibrosis in relation to the red tissue is %{}'.format(data.pfibvred))

#saves the images generated by the analysis
def saveOne(filename, savedir, data):
    if savedir is None or len(savedir) == 0:
        return
    filename = filename.split('.')[0]

    savename = '{}/{}_{{}}.jpeg'.format(savedir,filename)

    io.imsave(savename.format('original'), data.RGB)

    if settings.show_firstPass:
        io.imsave(savename.format('RedMask1'), coverUnMasked(data.RGB, data.redMask1))
        io.imsave(savename.format('BlueMask1'), coverUnMasked(data.RGB, data.blueMask1))
        io.imsave(savename.format('WhiteMask1'), coverUnMasked(data.RGB, data.whiteMask1))
        io.imsave(savename.format('OtherMask1'), coverUnMasked(data.RGB, data.otherMask1))

    io.imsave(savename.format('RedMaskFinal'), coverUnMasked(data.RGB, data.redMask2))
    io.imsave(savename.format('BlueMaskFinal'), coverUnMasked(data.RGB, data.blueMask2))
    io.imsave(savename.format('WhiteMaskFinal'), coverUnMasked(data.RGB, data.whiteMask2))
    io.imsave(savename.format('OtherMaskFinal'), coverUnMasked(data.RGB, data.otherMask2))

    io.imsave(savename.format('BeautiyBlue'), img_as_uint(color.hsv2rgb(data.beautifyBlue)))

#plots the images generated by analysis
def plotOne(filename, data):
    if not settings.show_images:
        return
    ## Display orginal image
    plt.figure();
    plt.title(filename);
    plt.axis('off')
    plt.imshow(data.RGB);

    if settings.show_firstPass:
        plt.figure(figsize = (1,2))
        plt.subplot(1,2,1)

        showMask(data.RGB, data.redMask1, 'Red Mask 1')
        plt.subplot(1,2,2)
        showMask(data.RGB, data.blueMask1, 'Blue Mask 1')

        plt.figure(figsize = (1,2))
        plt.subplot(1,2,1)
        showMask(data.RGB, data.whiteMask1, 'White Mask 1')
        plt.subplot(1,2,2)
        showMask(data.RGB, data.otherMask1, 'Other Mask 1')

    plt.figure(figsize = (1,2))
    plt.subplot(1,2,1)
    showMask(data.RGB, data.redMask2, 'Red Mask')
    plt.subplot(1,2,2)
    showMask(data.RGB, data.blueMask2, 'Blue Mask')

    plt.figure(figsize = (1,2))
    plt.subplot(1,2,1)
    showMask(data.RGB, data.whiteMask2, 'White Mask')
    plt.subplot(1,2,2)
    showMask(data.RGB, data.otherMask2, 'Other Mask')

    plt.figure()
    plt.title('Beautify Fibrosis')
    plt.axis('off')
    plt.imshow(color.hsv2rgb(data.beautifyBlue))

#process one file, dividing the file into blue (fibrosis), red (tissue), white, and unclassified
def processOne(im):
    RGB = np.asarray(im.convert('RGB'))
    HSV = np.asarray(im.convert('HSV'))
    LAB = color.rgb2lab(RGB)

#    test = LAB.copy()
#    test[...,0] = test[...,0]/100
#    test[...,1] = (test[...,1]-test[...,1].min())/(test[...,1].max()-test[...,1].min())
#    test[...,2] = (test[...,2]-test[...,2].min())/(test[...,2].max()-test[...,2].min())
#    print(LAB[...,1].max(),LAB[...,1].min())
#    print(LAB[...,2].max(),LAB[...,2].min())
#    plt.figure()
#    plt.imshow(test)

    #apply color filters
    whiteMask1, redMask1, blueMask1, otherMask1 = createColorMasks(HSV, RGB)
    otherwhiteMask = findWhite(whiteMask1,redMask1,blueMask1,otherMask1,LAB)
    otherMask = otherMask1 & np.logical_not(otherwhiteMask)
    whiteMask = whiteMask1 | otherwhiteMask

    #catagorize other
    otherredMask, otherblueMask, otherotherMask = findBlueAndRed(otherwhiteMask,redMask1,blueMask1,otherMask,LAB)

    redMask = redMask1 | otherredMask
    blueMask = blueMask1 | otherblueMask

    beautifyBlue = beautify(blueMask, HSV)
    colorCounts = {'red1':np.sum(redMask1),'blue1':np.sum(blueMask1),
                   'white1':np.sum(whiteMask1),'other1':np.sum(otherMask1),
                   'red2':np.sum(redMask),'blue2':np.sum(blueMask),
                   'white2':np.sum(whiteMask),'other2':np.sum(otherotherMask)
                   }
    # Calculate the area of the red pixels
    redcount = np.sum(redMask)
    bluecount = np.sum(blueMask)
    pfibvred=100*(bluecount/(bluecount+redcount))

    data = Data()
    data.RGB = RGB
    data.HSV = HSV
    data.redMask1 = redMask1
    data.blueMask1 = blueMask1
    data.whiteMask1 = whiteMask1
    data.otherMask1 = otherMask1
    data.redMask2 = redMask
    data.blueMask2 = blueMask
    data.whiteMask2 = whiteMask
    data.otherMask2 = otherotherMask
    data.beautifyBlue = beautifyBlue
    data.colorCounts = colorCounts
    data.pfibvred = pfibvred
    return data

#gethers user input and processes all files, saving and ploting as requested
def main():
    root = tk.Tk()
    root.withdraw()
    filepaths =  filedialog.askopenfilenames(title='Select Files for Fibrosis')
    if len(filepaths) == 0:
        return
    root = tk.Tk()
    root.withdraw()
    savefile = filedialog.asksaveasfile(title='Save Analysis to csv',defaultextension='.csv',filetypes=[('csv files', '.csv')])
    if savefile is not None:
        savefile.write('file name, % fibrosis, red count 1, blue count 1, white count 1, other count 1, red count 2, blue count 2, white count 2, other count 2\n')
    savedir = None
    if settings.save_images:
        savedir = filedialog.askdirectory(title='Directory to save images')


    for filepath in filepaths:
        im = Image.open(filepath)

        filename = filepath.split('/')[-1]
        data = processOne(im)

        bluePix1 = data.RGB[data.blueMask1][:,2]
        bluePix2 = data.RGB[data.blueMask2][:,2]
#        plt.figure()
#        plt.title(filename)
#        plt.hist(bluePix1,alpha=.8)
#        plt.hist(bluePix2,alpha=.8)

        printTextOne(filename, data)
        plotOne(filename, data)
        saveOne(filename, savedir, data)

        if savefile is not None:
            savefile.write('{}, {}, {red1}, {blue1}, {white1}, {other1}, {red2}, {blue2}, {white2}, {other2}\n'.format(filename,data.pfibvred,**data.colorCounts))
#    plt.show()
    if savefile is not None:
        savefile.close()

if __name__ == "__main__":
    main()
