import drawtetrado.structure as structure
import drawtetrado.svg_painter as svg_painter

from argparse import ArgumentParser

import os
import sys


def Draw(struct, output_file, config = svg_painter.Config(1.0)):
    root, ext = os.path.splitext(output_file)
    for idx in range(len(struct.tetrads)):
        quadruplex = structure.Quadruplex(struct, idx)
        svg_maker = svg_painter.SvgMaker(config, root + "_" + str(idx) + ext, \
                quadruplex)

        # OPTIMIZE, Takes argument "optimizer" with location to the optimizer
        # binary. Default is "./svg_optimizer"
        quadruplex.Optimize()

        # Prepare + Draw
        svg_maker.DrawAll()

        # Save
        svg_maker.svg.save(pretty=True)

        # Also draw sinle tetrads from quadruplex structure.
        if (len(struct.single_tetrads[idx]) > 1):
            for tetrad_idx in range(len(struct.single_tetrads[idx])):
                quadruplex = structure.Quadruplex(struct, idx, tetrad_idx)
                svg_maker = svg_painter.SvgMaker(config, root + "_" + str(idx) + \
                        "_" + str(tetrad_idx) + ext, quadruplex)

                # OPTIMIZE, Takes argument "optimizer" with location to the optimizer
                # binary. Default is "./svg_optimizer"
                quadruplex.Optimize()

                # Prepare + Draw
                svg_maker.DrawAll()

                # Save
                svg_maker.svg.save(pretty=True)

def DrawFromString(json, output_file, config = svg_painter.Config(1.0)):
    Draw(structure.Structure().fromString(json), output_file, config)


def DrawFromFile(filename_json, output_file, config = svg_painter.Config(1.0)):
    Draw(structure.Structure().fromFile(filename_json), output_file, config)

def ConfigFromArgs(args):
    config = svg_painter.Config(1.0)

    config.colors["connection"] = args.color_connection
    config.colors["border"] = args.color_border
    config.colors["text"] = args.color_text
    config.colors["anti"] = args.color_gb_anti
    config.colors["syn"] = args.color_gb_syn
    config.colors["n/a"] = args.color_gb_unknown

    if args.no_label_tilted:
        config.tilted_labels = False
    if args.no_label_nucleotide_full:
        config.label_nucleotide_full = False
    if args.no_label_nucleotide:
        config.label_nucleotide = False
        config.label_nucleotide_full = False
    if args.no_label_chain:
        config.label_chain = False
    if args.no_label_number:
        config.label_number = False

    config.font_family = args.label_font
    config.label_font_size = args.label_size
    config.se_label_font_size = args.se_label_size
    config.se_label_spacing = args.se_label_spacing

    config.point_stroke = args.line_width * 0.7
    config.stroke_width = args.line_width

    config.tetrade_spacing = args.tetrad_spacing
    config.angle = args.angle
    config.longer = args.nucl_longer
    config.shorter = args.nucl_shorter
    config.spacing = args.nucl_spacing

    return config

def main():
    parser = ArgumentParser('drawtetrado',
                            epilog='The output path is a template. For example, '
                            'if output=/tmp/out.svg, the resulting files will be /tmp/out_0.svg, '
                            '/tmp/out_1.svg and so on (for as many distinct quadruplexes as there '
                            'are in the input file)')
    parser.add_argument('input', help='path to input JSON generated by ElTetrado')
    parser.add_argument('output', help='path to output SVG file template')


    # Main quadruplex look
    parser.add_argument('--angle',
            help='Angle of the resulted drawing in degrees. Angle between front and left edges of '
            'the drawing. Reasonable values are probably within 70 and 40 deg. '
            '[default=50.0]',
            default=50.0,
            type=float)
    parser.add_argument('--tetrad-spacing',
            help='Spacing between tetrad layers. Spacing of 0 will result in back edge of lower '
            'layer aligning with front edge of the higher layer. '
            '[default=50.0]',
            default=50.0,
            type=float)
    parser.add_argument('--nucl-longer',
            help='Length of the "longer" edge of the nucleotide box. This value should be larger '
            'than --nucl-shorter to preserve proper visualization of ONZ positive and negative '
            'classification of the tetrad. '
            '[default=100.0]',
            default=100.0,
            type=float)
    parser.add_argument('--nucl-shorter',
            help='Lenght of the "shorter" edge of the nucleotide box. This value should be '
            'smaller than --nucl-longer to preserve proper visualization of ONZ positive and '
            'negative classification of the tetrad. '
            '[default=70.0]',
            default=70.0,
            type=float)
    parser.add_argument('--nucl-spacing',
            help='Spacing between individual nucleotides in the same tetrad layer. '
            '[default=10.0]',
            default=10.0,
            type=float)
    parser.add_argument('--line-width',
            help='Width of the lines on the drawing. Exact witdth of connection lines, tetrad '
            'border line. Points at the corners of tetrads are using 70%% of this value as width. '
            '[default=3.0]',
            default=3.0,
            type=float)

    # Parse labels
    parser.add_argument('--no-label-tilted',
            help='By default labels are skewed and put on labels. This means the text skew is '
            'affected by the --angle of the drawing and can be less readable with some '
            'configurations. Disabling it will at most rotate the text instead of skewing it.',
            action='store_true')
    parser.add_argument('--no-label-nucleotide-full',
            help='Exclude full name from the nucleotide label. Includes naming like DG instead of '
            'G, BRU instead of u. Full labels can provide more information about nucleotides.',
            action='store_true')
    parser.add_argument('--no-label-nucleotide',
            help='Exclude name from the nucleotide label like A, C, T, G '
            'Setting this flag also sets --no-label-nucleotide-full.',
            action='store_true')
    parser.add_argument('--no-label-chain',
            help='Exclude chain information from the nucleotide label.',
            action='store_true')
    parser.add_argument('--no-label-number',
            help='Exclude nucleotide index from the nucleotide label.',
            action='store_true')
    parser.add_argument('--label-font',
            help='Font family used for all labels. '
            '[default="Arial, Helvetica"]',
            default='Arial, Helvetica')
    parser.add_argument('--label-size',
            help='Font size of the nucleotide labels only. '
            '[default=20.0]',
            default=20.0,
            type=float)

    parser.add_argument('--se-label-size',
            help='Font size of 5\' and 3\' labels only. '
            '[default=24.0]',
            default=24.0,
            type=float)
    parser.add_argument('--se-label-spacing',
            help='Spacing between 5\', 3\' labels and nucleotide. Can put further away or closer '
            'to prevent potential overlap with strand between nucleotides. '
            '[default=20.0]',
            default=20.0,
            type=float)


    # Parse colors
    parser.add_argument('--color-connection',
            help='Color of connecting line between nucleotides in hex. '
            '[default="#000000"]',
            default='#000000')
    parser.add_argument('--color-border',
            help='Color of rectangular border of tetrad layer in hex. '
            '[default="#E23D28"]',
            default='#E23D28')
    parser.add_argument('--color-text',
            help='Color of nucleotide labels and 5\' 3\' labels in hex. '
            '[default="#000000"]',
            default='#000000')
    parser.add_argument('--color-gb-anti',
            help='Color of nucleotide box with anti glycosidic bond in hex. '
            '[default="#FFCC38"]',
            default='#FFCC38')
    parser.add_argument('--color-gb-syn',
            help='Color of nucleotide box with anti glycosidic bond in hex. '
            '[default="#FF992B"]',
            default='#FF992B')
    parser.add_argument('--color-gb-unknown',
            help='Color of nucleotide box with unknown glycosidic bond in hex. '
            '[default="#BB9977"]',
            default='#BB9977')
    args = parser.parse_args()

    config = ConfigFromArgs(args)

    if not args.input and args.output:
        print(parser.print_help())
        sys.exit(1)

    DrawFromFile(args.input, args.output, config)
