#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

# chimera - observatory automation system
# Copyright (C) 2006-2007  P. Henrique Silva <henrique@astro.ufsc.br>

# 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 2
# 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.


import sys

from chimera.core.cli import ChimeraCLI, action
from chimera.core.compat import freeze_support
from chimera.interfaces.pointverify import CanSetScopeButNotThisField, CantSetScopeException
from chimera.util.astrometrynet import NoSolutionAstrometryNetException
from chimera.util.astrometrynet import AstrometryNet


class ChimeraPointVerify(ChimeraCLI):
    def __init__(self):
        # are these entities being created or am I referring to existing things?
        # the first entry is how the script will be called
        # the second entry is an English language description of the script
        ChimeraCLI.__init__(self, "chimera-pverify", "Point Verifier", 0.1)
        self.addHelpGroup("PVERIFY", "PVerify")
        self.addController(name="pverify", cls="PointVerify", required=True, helpGroup="PVERIFY",
                           help="Pointing verification controller to be used")
        # self.addParameters(
        #     dict(name="pverify_file", long="fname", type="string", helpGroup="PVERIFY", help="Does astrometry on file",
        #          metavar="FILE"))

        self.addParameters(dict(name="nfields", long="nfields", type="int", helpGroup="PVERIFY",
                                help="Number of fields to verify", default=1))
        self.addParameters(dict(name="binning", help="Use binning to expose", helpGroup="PVERIFY"))

    # ok, looks like action establishes that the following method is some
    # action performed by this script
    @action(long="choose",
            help="Chooses a field to point the scope to, moves the scope, takes an image and verifies the pointing",
            helpGroup="PVERIFY")
    def checkPointing(self, options):
        """
        Chooses a field to point the scope to, moves the scope, 
        takes an image and verifies the pointing
        """
        self.out("Choosing a field in the sky, moving scope and taking images")
        for i_field in range(options.nfields):
            try:
                    self.pverify.setCurrentField(i_field)
                    self.pverify.checkPointing()
            # what is this e for ???
            except CantSetScopeException:
                self.exit("Can't set scope")
            raw_input("Field %d OK. Press ENTER for next..." % i_field)

    @action(long="file",
            type="string",
            help="Does astrometry on file",
            helpGroup="PVERIFY")
    def file(self, options):
        """
        Returns a new image with new WCS
        """
        self.out("Doing astrometry on file : %s\n", options.file)
        try:
            AstrometryNet.solveField(options.file, findstarmethod="sex")
        except NoSolutionAstrometryNetException:
            try:
                AstrometryNet.solveField(
                    options.file, findstarmethod="astrometry.net")
            except NoSolutionAstrometryNetException:
                self.exit("Can't set scope")
        self.out("OK")

    @action(long="here",
            help="Takes an image where telescope is pointed to, tries to find image RA, DEC, and tries to recenter the telescope",
            helpGroup="PVERIFY")
    def checkHere(self, options):
        """
        Takes an image where telescope is pointed to,
        tries to find image RA, DEC,
        and tries to recenter the telescope
        """

        # Check binning

        if options.binning:
            binnings = self.pverify.getCam().getBinnings()
            if options.binning not in binnings.keys():
                self.exit("Invalid binning mode. See chimera-cam --info for available binning modes")
            imageRequest = dict(binning=options.binning)
        else:
            imageRequest = dict()

        self.out("Centering scope on current field")
        try:
            self.pverify.ntrials = 0
            self.pverify.pointVerify(imageRequest)
        except CanSetScopeButNotThisField:
            self.out("The scope has been set on a standard field but it is impossible to set on this - either spotty clouds or too faint stars")
        self.out("OK")


def main():
    cli = ChimeraPointVerify()
    cli.run(sys.argv)
    cli.wait()


if __name__ == '__main__':
    freeze_support()
    main()
