#!/usr/bin/env python
#
#  Copyright (C) 2022, 2025  Smithsonian Astrophysical Observatory
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License along
#  with this program; if not, write to the Free Software Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

'Add a special grating region coordinates vector to ds9'

import sys

from dax.utils import xpaset, xpaget


def get_zero_order_location(xpa):
    'Get 0th order location from [REGION] block'
    infile = xpaget(xpa, "file")
    infile = infile.split("[")[0]     # Strip of block name/etc

    from pycrates import read_file
    try:
        regblock = read_file(infile+"[REGION][shape=circle]")
    except Exception as badstuff:
        raise RuntimeError("Unable to open REGION extension, is this a gratings dataset?") from badstuff

    xpos = regblock.get_column("x").values
    ypos = regblock.get_column("y").values

    if len(xpos) != 1:
        raise ValueError("ERROR: There should only be 1 circle defining 0th order location")

    roll = regblock.get_key_value("ROLL_PNT")  # pos ang vs cartesian

    x0 = xpos[0]
    y0 = ypos[0]
    return x0, y0, roll


def alt_get_zero_order(xpa):
    'Get 0th order from center of display instead'

    coords = xpaget(xpa, "pan physical").strip()
    x0, y0 = [float(aa) for aa in coords.split()]
    roll = xpaget(xpa, "fits header keyword ROLL_PNT").strip()
    if roll == '':
        roll = 0
    else:
        roll = float(roll)

    return x0, y0, roll


def make_default_line(x0, y0, roll, dx=500, dy=500):
    'Get end point for the default line, try to match roll of obs.'

    from math import cos, sin, radians
    roll_r = radians(-roll)
    cos_roll = cos(roll_r)
    sin_roll = sin(roll_r)

    x1 = dx * cos_roll + dy * sin_roll + x0
    y1 = -1 * dx * sin_roll + dy * cos_roll + y0

    return x1, y1


def main():
    'Main routine'
    xpa = sys.argv[1]

    try:
        x0, y0, roll = get_zero_order_location(xpa)
    except Exception:
        sys.stderr.write("WARNING: Could not locate 0th order in [REGION] block; using center of display instead.\n")
        x0, y0, roll = alt_get_zero_order(xpa)


    x1, y1 = make_default_line(x0, y0, roll)

    reg_str = f"""global font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source
physical
line({x0},{y0},{x1},{y1}) # line=0 1 callback=edit {{run_tgcoords}} "0" callback=move {{run_tgcoords}} "0" color=goldenrod dashlist=4 4 tag={{tgcoords}}
"""

    xpaset(xpa, "regions -format ds9", reg_str)


if __name__ == "__main__":
    main()
