#! /usr/bin/env python
from __future__ import print_function

"""
MIMAS - The Multi-resolution Image Mask for Aegean Software

Created: Paul Hancock, Oct 2014

TODO: Write an in/out reader for MOC formats described by
http://arxiv.org/abs/1505.02937

"""

import argparse
import sys
from AegeanTools import MIMAS, __citation__


if __name__ == "__main__":
    epilog = 'Regions are added/subtracted in the following order, +r -r +c -c +p -p. ' + \
             'This means that you might have to take multiple passes to construct overly complicated regions.'
    parser = argparse.ArgumentParser(epilog=epilog, prefix_chars='+-')

    group1 = parser.add_argument_group('Creating/modifying regions', 'Must specify -o, plus or more [+-][cr]')
    # tools for creating .mim files
    group1.add_argument('-o', dest='outfile', action='store', help='output filename', default=None)
    group1.add_argument('-depth', dest='maxdepth', action='store',
                        metavar='N', default=8, type=int,
                        help='maximum nside=2**N to be used to represent this region. [Default=8]')
    group1.add_argument('+r', dest='add_region', action='append',
                        default=[], type=str, metavar='filename', nargs='*',
                        help='add a region specified by the given file (.mim format)')
    group1.add_argument('-r', dest='rem_region', action='append',
                        default=[], type=str, metavar='filename', nargs='*',
                        help='exclude a region specified by the given file ( .mim format)')
    # add/remove circles
    group1.add_argument('+c', dest='include_circles', action='append',
                        default=[], type=float, metavar=('ra', 'dec', 'radius'), nargs=3,
                        help='add a circle to this region (decimal degrees)')
    group1.add_argument('-c', dest='exclude_circles', action='append',
                        default=[], type=float, metavar=('ra', 'dec', 'radius'), nargs=3,
                        help='exclude the given circles from a region')

    # add/remove polygons
    group1.add_argument('+p', dest='include_polygons', action='append',
                        default=[], type=float, metavar=('ra', 'dec'), nargs='*',
                        help='add a polygon to this region ( decimal degrees)')
    group1.add_argument('-p', dest='exclude_polygons', action='append',
                        default=[], type=float, metavar=('ra', 'dec'), nargs='*',
                        help='remove a polygon from this region ( decimal degrees)')
    group1.add_argument('-g', dest='galactic', action='store_true', default=False,
                        help='Interpret input coordinates are galactic instead of equatorial.')

    group2 = parser.add_argument_group("Using already created regions")
    # tools that use .mim files
    group2.add_argument('--mim2reg', dest='mim2reg', action='append',
                        type=str, metavar=('region.mim', 'region.reg'), nargs=2,
                        help='convert region.mim into region.reg', default=[])
    group2.add_argument('--reg2mim', dest='reg2mim', action='append',
                        type=str, metavar=('region.reg', 'region.mim'), nargs=2,
                        help="Converta a .reg file into a .mim file", default=[])
    group2.add_argument('--mim2fits', dest='mim2fits', action='append',
                        type=str, metavar=('region.mim', 'region_MOC.fits'), nargs=2,
                        help="Convert a .mim file into a MOC.fits file", default=[])
    group2.add_argument('--intersect', '+i', dest='intersect', action='append', type=str, default=[],
                        metavar=('region.mim',), help="Write out the intersection of the given regions.")
    group2.add_argument('--area', dest='area', action='store', default=None,
                        help="Report the area of a given region", metavar=("region.mim",))
    group3 = parser.add_argument_group("Masking files with regions")
    group3.add_argument('--maskcat', dest='mask_cat', action='store',
                        type=str, metavar=('region.mim', 'INCAT', 'OUTCAT'), nargs=3, default=[],
                        help='use region.mim as a mask on INCAT, writing OUTCAT')
    group3.add_argument('--maskimage', dest='mask_image', action='store',
                        type=str, metavar=('region.mim', 'file.fits', 'masked.fits'), nargs=3, default=[],
                        help='use region.mim to mask the image file.fits and write masekd.fits')
    group3.add_argument('--fitsmask', dest='fits_mask', action='store',
                        type=str, metavar=('mask.fits', 'file.fits', 'masked_file.fits'), nargs=3, default=[],
                        help='Use a fits file as a mask for another fits file. ' +
                             'Values of blank/nan/zero are considered to be mask=True.')
    group3.add_argument('--negate', dest='negate', action='store_true', default=False,
                        help='By default all masks will exclude data that are within the given region. ' +
                             'Use --negate to exclude data that is outside of the region instead.')
    group3.add_argument('--colnames', dest='radec_colnames', action='store',
                        type=str, metavar=('RA_name', 'DEC_name'),  nargs=2, default=('ra', 'dec'),
                        help='The name of the columns which contain the RA/DEC data. Default=(ra,dec).')

    group4 = parser.add_argument_group('Extra options')
    # extras
    group4.add_argument('--fitsimage', dest='mim2img', action='store_true',
                        default=False, help='Save the region as a fits image')
    group4.add_argument('--debug', dest='debug', action='store_true', help='debug mode [default=False]', default=False)
    group4.add_argument('--version', action='version', version='%(prog)s '+MIMAS.__version__+"-({0})".format(MIMAS.__date__))
    group4.add_argument('--cite', dest='cite', action="store_true", default=False,
                        help='Show citation information.')

    results = parser.parse_args()

    if results.cite:
        print(__citation__)
        sys.exit(0)

    # TODO: see if there is an 'argparse' way of detecting no input
    if len(sys.argv) <= 1:
        parser.print_help()
        sys.exit()

    # get the MIMAS logger
    logging = MIMAS.logging
    logging_level = logging.DEBUG if results.debug else logging.INFO
    logging.basicConfig(level=logging_level, format="%(process)d:%(levelname)s %(message)s")
    logging.info("This is MIMAS {0}-({1})".format(MIMAS.__version__, MIMAS.__date__))

    if len(results.fits_mask) > 0:
        logging.info("The --fitsmask option is not yet implemented.")
        sys.exit(1)

    if len(results.mim2reg) > 0:
        for i, o in results.mim2reg:
            MIMAS.mim2reg(i, o)
        sys.exit()

    if len(results.reg2mim) > 0:
        for i, o in results.reg2mim:
            MIMAS.reg2mim(i, o, results.maxdepth)
        sys.exit()

    if len(results.mim2fits) > 0:
        for i, o in results.mim2fits:
            MIMAS.mim2fits(i, o)
        sys.exit()

    if results.area is not None:
        region = MIMAS.cPickle.load(open(results.area))
        print("{0} represents an area of {1} deg^2".format(results.area, region.get_area()))
        sys.exit()

    if len(results.intersect) > 0:
        if len(results.intersect) == 1:
            print("intersections requires at least two regions")
            sys.exit(1)
        elif results.outfile is None:
            print("outfile is required")
            sys.exit(1)
        else:
            region = MIMAS.intersect_regions(results.intersect)
            MIMAS.save_region(region, results.outfile)
        sys.exit()

    if len(results.mask_image) > 0:
        m, i, o = results.mask_image
        MIMAS.mask_file(m, i, o, results.negate)
        sys.exit()

    if len(results.mask_cat) > 0:
        m, i, o = results.mask_cat
        racol, deccol = results.radec_colnames
        MIMAS.mask_catalog(m, i, o, results.negate, racol, deccol)
        sys.exit()

    if results.mim2img:
        region = MIMAS.combine_regions(results)
        MIMAS.save_as_image(region, results.outfile)
        sys.exit()

    if results.outfile is not None:
        region = MIMAS.combine_regions(results)
        MIMAS.save_region(region, results.outfile)


