#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import logging
import time

import json
import click
import matplotlib.pyplot as plt

import orangery as o
from orangery.cli import defaults, util
from orangery.tools.plotting import get_scale_factor


@click.command(options_metavar='<options>')
@click.argument('file1', nargs=1, type=click.Path(exists=True), metavar='<file_t0>') # help="survey representing the initial condition"
@click.argument('file2', nargs=1, type=click.Path(exists=True), metavar='<file_t1>') # help="survey representing the final condition"
@click.argument('fields', nargs=1, metavar='<fields>') # help="character string identifying the columns"
@click.argument('xs_name', nargs=1, metavar='<name>') # help="name of the cross-section to plot"
@click.option('--codes', 'codes_f', nargs=1, type=click.Path(exists=True), metavar='<codes_file>', help="JSON file representing the usage intent of a set of survey codes")
@click.option('--show/--save', is_flag=True, default=True, help="Show the plot or save to files; --show is the default")
@click.option('--summary/--no-summary', default=True, help="Print summary information; --summary is the default")
@click.option('--units', type=click.Choice(['m','sft','ft']), default='m', help="Unit to show in axis labels")
@click.option('--labels', nargs=2, metavar='<text text>', help="Labels to display in the legend")
@click.option('--exaggeration', metavar='<int>', default=3, help="Vertical exaggeration of plot")
@click.option('--scale', nargs=2, metavar='<float int>', type=click.Tuple([float, int]), default=(10, 300), help="Scale where first argument is units per-inch on the horizontal axis and second argument is output DPI")
@click.option('--close/--no-close', default=True, help="Close the line ends; --close is the default")
@click.option('--reverse', type=click.Choice(['t0','t1','tx']), help="Reverse a line or lines of section (t0=initial, t1=final, tx=both)")
@click.option('--exclude', nargs=2, type=click.Tuple([str, click.Choice(['t0','t1','tx'])]), multiple=True, metavar='<str choice>', help="Exclude a survey code from a line or lines of section (t0=initial, t1=final, tx=both)")
@click.option('--overlay', nargs=1, type=click.Path(exists=True))
@click.option('-v', '--verbose', is_flag=True, help="Enables verbose mode")
def cutfill(file1, file2, fields, xs_name, codes_f, show, summary, units, labels, exaggeration, scale, close, reverse, exclude, overlay, verbose):
    """Displays a plot of a repeat survey with cut and fill.

    \b
    The cutfill subcommand takes four arguments:
    <file_t0> : survey data representing the initial condition in csv format
    <file_t1> : survey data representing the final condition in csv format
    <fields> : series of characters describing the data columns
    <name> : name of cross-section to plot

    Options allow to set various properties of the plot. The default is to --show the plot.
    With the --save option the plot will be saved as an image along with a csv file containing
    data about cross-sectional cut-and-fill areas along the line of secion.

    \b
    Example:
    orangery cutfill file_2004.csv file_2010.csv pxyzctr XS-7 --reverse t0

    """
    if verbose is True:
        loglevel = 2
    else:
        loglevel = 0

    logging.basicConfig(stream=sys.stderr, level=loglevel or logging.INFO)

    # load the configuration
    codes = defaults.codes.copy()
    if codes_f:
        user_codes = util.load_config(codes_f)
        codes.update(user_codes)

    # load the survey data
    s1 = o.Survey(file1, fields, codes, 0)
    s2 = o.Survey(file2, fields, codes, 0)

    if overlay:
        s3 = o.Survey(overlay, fields, codes, 0)

    exclude_t0 = []
    exclude_t1 = []
    for code in exclude:
        if code[1] in ('t0', 'tx'):
            exclude_t0.append(code[0])
        if code[1] in ('t1', 'tx'):
            exclude_t1.append(code[0])

    # select a group of points, in this case a cross section
    xs_pts1 = o.group(s1.data, s1.code_table, group=xs_name, exclude=exclude_t0)
    xs_pts2 = o.group(s2.data, s2.code_table, group=xs_name, exclude=exclude_t1)

    # xs_pts_overlay = o.group(s3.data, s3.code_table, group=xs_name)

    # get the endpoints of the group
    p1, p2 = o.endpoints(xs_pts1, reverse=reverse in ('t0','tx'))

    # make the sections
    xs1 = o.Section(xs_pts1, p1, p2, reverse=reverse in ('t0','tx'))
    xs2 = o.Section(xs_pts2, p1, p2, reverse=reverse in ('t1','tx'))

    # xs_overlay = o.Section(xs_pts_overlay, p1, p2)

    if labels:
        label_t0 = labels[0]
        label_t1 = labels[1]
        label_overlay = labels[3]
    elif 't' in fields:
        label_t0 = (xs1.data.iloc[0]['t']).split('T')[0]
        label_t1 = (xs2.data.iloc[0]['t']).split('T')[0]
        # label_overlay = (xs_overlay.data.iloc[0]['t']).split('T')[0]
    else:
        label_t0 = 't0'
        label_t1 = 't1'
        # label_overlay = 'pre-restoration'

    # calculate the change
    chg = o.Change(xs1, xs2, close_ends=close)
    if summary:
        chg.summarize()

    import matplotlib
    font = {'family':'normal','weight':'normal','size':16}
    matplotlib.rc('font', **font)
    # plot the change between two cross-sections
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.set_aspect(exaggeration)

    # xs_overlay.plot(ax=ax, marker='None', linestyle='-', linewidth=3, color='tab:red', label=label_overlay)
    xs1.plot(ax=ax, marker='o', markersize=4, markerfacecolor='white', markeredgecolor='black', linestyle='-', color='gray', label=label_t0)
    xs2.plot(ax=ax, marker='o', markersize=4, markerfacecolor='black', markeredgecolor='black', linestyle='-', color='black', label=label_t1)
    chg.polygon_plot(ax=ax, fill_label='Fill', cut_label='Cut')
    chg.annotate_plot(ax=ax)
    ax.set_xlabel('Distance ({0})'.format(units))
    ax.set_ylabel('Elevation ({0}), {1}x exaggeration'.format(units, exaggeration))
    plt.legend(loc='best')
    plt.title('Cross-section {0}'.format(xs_name))

    if show:
        plt.show()
    else:
        fname = xs_name + '-' + label_t0.replace('-', '') + '-' + label_t1.replace('-', '')

        scale_factor = get_scale_factor(fig, ax, scale[0])
        dims = fig.get_size_inches()
        fig.set_size_inches(dims[0]*scale_factor, dims[1]*scale_factor)
        fig.savefig(fname+'.png', dpi=scale[1])
        click.echo('Figure saved to: {}'.format(fname+'.png'))

        chg.save(fname+'.csv')
        click.echo('Data saved to: {}'.format(fname+'.csv'))

[(17, 'click.command', 'click.command', False, 'import click\n'), (20, 'click.argument', 'click.argument', False, 'import click\n'), (21, 'click.argument', 'click.argument', False, 'import click\n'), (23, 'click.option', 'click.option', False, 'import click\n'), (24, 'click.option', 'click.option', False, 'import click\n'), (26, 'click.option', 'click.option', False, 'import click\n'), (27, 'click.option', 'click.option', False, 'import click\n'), (29, 'click.option', 'click.option', False, 'import click\n'), (33, 'click.option', 'click.option', False, 'import click\n'), (58, 'logging.basicConfig', 'logging.basicConfig', False, 'import logging\n'), (61, 'orangery.cli.defaults.codes.copy', 'defaults.codes.copy', False, 'from orangery.cli import defaults, util\n'), (67, 'orangery.Survey', 'o.Survey', True, 'import orangery as o\n'), (68, 'orangery.Survey', 'o.Survey', True, 'import orangery as o\n'), (82, 'orangery.group', 'o.group', True, 'import orangery as o\n'), (83, 'orangery.group', 'o.group', True, 'import orangery as o\n'), (88, 'orangery.endpoints', 'o.endpoints', True, 'import orangery as o\n'), (91, 'orangery.Section', 'o.Section', True, 'import orangery as o\n'), (92, 'orangery.Section', 'o.Section', True, 'import orangery as o\n'), (110, 'orangery.Change', 'o.Change', True, 'import orangery as o\n'), (116, 'matplotlib.rc', 'matplotlib.rc', False, 'import matplotlib\n'), (118, 'matplotlib.pyplot.figure', 'plt.figure', True, 'import matplotlib.pyplot as plt\n'), (129, 'matplotlib.pyplot.legend', 'plt.legend', True, 'import matplotlib.pyplot as plt\n'), (63, 'orangery.cli.util.load_config', 'util.load_config', False, 'from orangery.cli import defaults, util\n'), (71, 'orangery.Survey', 'o.Survey', True, 'import orangery as o\n'), (133, 'matplotlib.pyplot.show', 'plt.show', True, 'import matplotlib.pyplot as plt\n'), (137, 'orangery.tools.plotting.get_scale_factor', 'get_scale_factor', False, 'from orangery.tools.plotting import get_scale_factor\n'), (18, 'click.Path', 'click.Path', False, 'import click\n'), (19, 'click.Path', 'click.Path', False, 'import click\n'), (22, 'click.Path', 'click.Path', False, 'import click\n'), (25, 'click.Choice', 'click.Choice', False, 'import click\n'), (28, 'click.Tuple', 'click.Tuple', False, 'import click\n'), (30, 'click.Choice', 'click.Choice', False, 'import click\n'), (32, 'click.Path', 'click.Path', False, 'import click\n'), (31, 'click.Choice', 'click.Choice', False, 'import click\n')]