import sys
import os

import math
import argparse
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick


def make_dataset_plots(csv_path, output_folder):
    df = pd.read_csv(csv_path)
    cut = df[df["Cut"] == "Cut"]
    uncut = df[df["Cut"] == "Uncut"]

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    fontdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
        'utilities', 'assets', 'fonts')
    for font in matplotlib.font_manager.findSystemFonts(fontdir):
        matplotlib.font_manager.fontManager.addfont(font)
    plt.rc('font', family='serif')
    plt.rc('font', serif='Linux Libertine')
    plt.rc('axes', titlesize=20)
    plt.rc('axes', labelsize=20)
    plt.rc('xtick', labelsize=20)
    plt.rc('ytick', labelsize=20)
    plt.rc('legend', fontsize=20)
    plt.rc('font', size=20)
    palette = 'Set1'
    palette_colors = plt.cm.get_cmap(palette).colors

    print(df[df["Boundary Segments"] == max(df["Boundary Segments"])])
    print(df[df["Boundary Segments"] == max(df["Boundary Segments"])]["Boundary Segments"])

    print(f'Med bdry seg: {df["Boundary Segments"].median()}')
    print(f'Med cut bdry seg: {cut["Boundary Segments"].median()}')
    print(f'Med uncut bdry seg: {uncut["Boundary Segments"].median()}')

    #Number of faces plot
    plt.figure(figsize=(10,5), tight_layout=True)
    bins = np.logspace(math.log(min(df["Faces"]), 10.),
        math.log(max(df["Faces"]), 10.),
        num=50)
    plt.xscale('log')
    p = plt.hist((uncut["Faces"], cut["Faces"]),
        label=("uncut", "cut"),
        bins=bins,
        alpha=0.5,
        histtype='stepfilled',
        color=palette_colors[:2])
    plt.gca().set(title="",
        xlabel='number of faces per mesh',
        ylabel='count')
    plt.legend()
    plt.savefig(os.path.join(output_folder, "num_faces.pdf"), dpi=300)
    plt.close()

    #Genus plot
    plt.figure(figsize=(10,5), tight_layout=True)
    p = plt.hist((uncut["Genus"].dropna(), cut["Genus"].dropna()),
        label=("uncut", "cut"),
        bins=10,
        alpha=0.5,
        log=True,
        histtype='bar',
        color=palette_colors[:2])
    plt.gca().set(title="",
        xlabel='genus',
        ylabel='count')
    plt.legend()
    plt.savefig(os.path.join(output_folder, "genus_all.pdf"), dpi=300)
    plt.close()

    #Genus plot small
    plt.figure(figsize=(10,5), tight_layout=True)
    p = plt.hist((uncut[uncut["Genus"]<=10]["Genus"], cut[cut["Genus"]<=10]["Genus"]),
        label=("uncut", "cut"),
        bins=10,
        alpha=0.5,
        log=True,
        histtype='bar',
        color=palette_colors[:2])
    plt.gca().set(title="",
        xlabel='genus (only meshes with genus ≤10)',
        ylabel='count')
    plt.legend()
    plt.savefig(os.path.join(output_folder, "num_genus_small.pdf"), dpi=300)
    plt.close()

    #Number of boundary segments plot
    plt.figure(figsize=(10,5), tight_layout=True)
    p = plt.hist((uncut["Boundary Segments"], cut["Boundary Segments"]),
        label=("uncut", "cut"),
        bins=12,
        alpha=0.5,
        histtype='bar',
        log=True,
        color=palette_colors[:2])
    plt.gca().set(title="",
        xlabel='number of boundary segments per mesh',
        ylabel='count')
    plt.legend()
    plt.savefig(os.path.join(output_folder, "num_bdry_segments.pdf"), dpi=300)
    plt.close()

    #Number of boundary segments plot small
    plt.figure(figsize=(10,5), tight_layout=True)
    p = plt.hist((uncut[uncut["Boundary Segments"]<=10]["Boundary Segments"],
        cut[cut["Boundary Segments"]<=10]["Boundary Segments"]),
        label=("uncut", "cut"),
        bins=10,
        alpha=0.5,
        histtype='bar',
        log=True,
        color=palette_colors[:2])
    plt.gca().set(title="",
        xlabel='number of boundary segments per mesh (only meshes with ≤10 segments)',
        ylabel='count')
    plt.legend()
    plt.savefig(os.path.join(output_folder, "num_bdry_segments_small.pdf"), dpi=300)
    plt.close()

    # Percentage boundary faces plot
    plt.figure(figsize=(10,5), tight_layout=True)
    plt.gca().xaxis.set_major_formatter(mtick.PercentFormatter(1))
    p = plt.hist((uncut["Boundary Faces"]/uncut["Faces"],
        cut["Boundary Faces"]/cut["Faces"]),
        label=("uncut", "cut"),
        bins=10,
        alpha=0.5,
        histtype='bar',
        color=palette_colors[:2])
    plt.gca().set(title="",
        xlabel='percentage of boundary faces',
        ylabel='count')
    plt.legend()
    plt.savefig(os.path.join(output_folder, "percent_boundary_faces.pdf"), dpi=300)
    plt.close()

    # Various pie charts
    palette = 'Accent'
    palette_colors = plt.cm.get_cmap(palette).colors
    plt.rc('axes', titlesize=24)
    plt.rc('axes', labelsize=18)
    plt.rc('xtick', labelsize=18)
    plt.rc('ytick', labelsize=18)
    plt.rc('legend', fontsize=18)
    plt.rc('font', size=18)

    plt.figure(figsize=(5,5), tight_layout=True)
    face_nums = [
    (cut["Faces"] > 100).sum(),
    (cut["Faces"] <= 100).sum(),
    (uncut["Faces"] > 100).sum(),
    (uncut["Faces"] <= 100).sum()
    ]
    plt.pie(face_nums,
        labels=["cut large", "cut\nsmall", "uncut large", "uncut\nsmall"],
        autopct='%1.0f%%',
        colors=palette_colors[:4])
    plt.gca().set(title="mesh size (faces ≤/>10)")
    plt.savefig(os.path.join(output_folder, "pie_face_num.pdf"), dpi=300)
    plt.close()

    diskiness = [
    ((cut["Manifold"]==True) & (cut["Genus"]==0) & (cut["Boundary Segments"]==1)).sum(),
    (~((cut["Manifold"]==True) & (cut["Genus"]==0) & (cut["Boundary Segments"]==1))).sum(),
    ((uncut["Manifold"]==True) & (uncut["Genus"]==0) & (uncut["Boundary Segments"]==1)).sum(),
    (~((uncut["Manifold"]==True) & (uncut["Genus"]==0) & (uncut["Boundary Segments"]==1))).sum()
    ]
    plt.figure(figsize=(5,5), tight_layout=True)
    plt.pie(diskiness,
        labels=["cut disk", "cut non-\ndisk", "uncut disk", "uncut\nnon-disk"],
        autopct='%1.0f%%',
        colors=palette_colors[:4])
    plt.gca().set(title="disk topology (only manifold)")
    plt.savefig(os.path.join(output_folder, "pie_disk.pdf"), dpi=300)
    plt.close()

    closedness = [
    (cut["Closed"]==True).sum(),
    (~(cut["Closed"]==True)).sum(),
    (uncut["Closed"]==True).sum(),
    (~(uncut["Closed"]==True)).sum()
    ]
    plt.figure(figsize=(5,5), tight_layout=True)
    plt.pie(closedness,
        labels=["cut closed", "cut non-\nclosed", "uncut closed", "uncut\nnon-closed"],
        autopct='%1.0f%%',
        colors=palette_colors[:4])
    plt.gca().set(title="mesh closedness")
    plt.savefig(os.path.join(output_folder, "pie_closed.pdf"), dpi=300)
    plt.close()

    manifoldness = [
    (cut["Manifold"]==True).sum(),
    (~(cut["Manifold"]==True)).sum(),
    (uncut["Manifold"]==True).sum(),
    (~(uncut["Manifold"]==True)).sum()
    ]
    plt.figure(figsize=(5,5), tight_layout=True)
    plt.pie(manifoldness,
        labels=["cut manifold", "cut non-\nmanifold", "uncut manifold", "uncut\nnonmanifold"],
        autopct='%1.0f%%',
        colors=palette_colors[:4])
    plt.gca().set(title="mesh manifoldness")
    plt.savefig(os.path.join(output_folder, "pie_manifold.pdf"), dpi=300)
    plt.close()

    return None
    
    
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Given dataset characteristig CSV, generate a few plots.")
    parser.add_argument("-c", "--csv", type=str, required=True, dest="csv")
    parser.add_argument("-o", "--output", type=str, required=True, dest="output")
    
    args = parser.parse_args()
    csv_path = os.path.abspath(args.csv)
    output_folder = os.path.abspath(args.output)
    
    make_dataset_plots(csv_path, output_folder)
