package LibNEOCP;

our $local=0;
our $db_tunnel=0;

use strict;
use warnings;

use Astro::Time;
use DBI;
#use NEOCPEphemerides;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(write_fp_files
                    write_obs_files
                    connect_database
                    convert_to_mjd);

my $use_mops=0; # is a full mops installation available?

# define ranges of uncertainty for matching ephemerides with trackets
our $v_error; # velocity +/- uncertainty
our $ra_error; # ra +/- uncertainty
our $dec_error; # dec +/- uncertainty
our $pa_error; # position angle +/- uncertainty

our $tracklet; # MOPS tracklet object reference
our $ephemeris; # NEOCP ephemeris object reference

# Process ephemerides and MOPS fields using fieldProximity
# Determine intersections of MOPS fields and objects with calculated ephemerides data

# Retrieve ephemerides data.
# Write a temporary file in MOPS track format.
#
# FP input file format for ephemerides is like
# S1529AW 54115.000000000000 226.983770423542 -15.936611863088 22.660571516119
# S1529AW 54116.000000000000 227.303808382276 -16.036101792784 22.655165465575
# S1529AW 54117.000000000000 227.621794297722 -16.134521970471 22.649599558459
sub write_fp_files {
    my ($dbh)=shift;
    my ($designation)=@_;
    
    my $sql="SELECT * FROM ephemerides WHERE designation=?";
    my $sth=$dbh->prepare($sql);
    $sth->execute($designation);
    my $ref;
    my $field_cnt=0;
    
    my $filename="$designation.ephem";
    
    open(FILE,">$filename");
    
    open(FILE2,">$designation-dummy.fields");
    
    while($ref=$sth->fetchrow_hashref()) { # iterate over all db records
        my $obj_label=$ref->{designation};
        my $mjd=$ref->{mjd_datetime};
        my $ra=$ref->{ra};
        my $dec=$ref->{dec};
        my $mag=$ref->{mag_v};
        
        print FILE "$obj_label $mjd $ra $dec $mag\n";
        
        $field_cnt++;
        print FILE2 "$field_cnt $mjd $ra $dec 3.58249279286511\n";
    }
    
    close(FILE);
    close(FILE2);
}

# Write observations retrieved from MPC in MOPS compatible format
sub write_obs_files {
    my ($dbh)=shift;
    my ($designation)=@_;
    
    my $sql="SELECT * FROM observations WHERE designation=?";
    my $sth=$dbh->prepare($sql);
    $sth->execute($designation);
    my $ref;
    
    my $filename="$designation.obs";
    
    open(FILE,">$filename");
       
    while($ref=$sth->fetchrow_hashref()) { # iterate over all db records
        my $obj_label=$ref->{designation};
        my $day; my $month; my $year; my $ut;
        $day=$ref->{day};
        $month=$ref->{month};
        $year=$ref->{year};
        # $ut=$ref->{hour} / 24; # fractional hour
        $ut=0;
        my $mjd=cal2mjd($day,$month,$year,$ut);
        my $ra=15 * ($ref->{ra_hr} + ($ref->{ra_min} / 60) +  ($ref->{ra_sec} / 3600));
        my $dec=abs($ref->{dec_deg}) + ($ref->{dec_min} / 60) + ($ref->{dec_sec} / 3600);
        if($ref->{dec_deg} < 0) { $dec*=-1; } # account for neg sign
        my $mag;
        if($ref->{magnitude}){
            $mag=$ref->{magnitude};
        } else { $mag=""; } # magnitude is not available for the observation
        print FILE "$obj_label $mjd $ra $dec $mag\n";
        print "";
    }
    
    close(FILE);
}


# For each MOPS tracklet in an intersecting field, compare it with the NEO CP ephemeris.
# Compare by velocity
# - the MOPS total velocity matches the predicted velocity within some range of uncertainty
# Compare by position
# - the RA and DEC match within some range of uncertainty

# Compare a MOPS tracklet to the ephemerides of an NEO CP object.
# Return 1 if the given tracklet is a candidate for a match with a predicted object
# Otherwise return 0.
#
# Ephemeris object structure
# hash reference
sub evaluate_tracklets {
    my ($tracklet_id, $ephem)=@_;

    # Compare total velocity to the ephemerides velocity.
    my $v_tracklet=$tracklet->{velocity};
    my $v_neocp;
    
    my $ra_tracklet=$tracklet->{ra};
    my $ra_neocp=$ephemeris->{ra};
    my $dec_tracklet=$tracklet->{dec};
    my $dec_neocp=$ephemeris->{dec};
    my $pa_tracklet=$tracklet->{pa};
    my $pa_neocp=$ephemeris->{pa};
    
    my $v_match=0; # velocity match
    my $ra_match=0; # ra position match
    my $dec_match=0; # dec position match
    my $pa_match=0; # position angle match
    
    if( $v_tracklet<=($v_neocp + $v_error) || $v_tracklet>=($v_neocp - $v_error) ) {
        $v_match=1;
    }
    if( $ra_tracklet<=($ra_neocp + $ra_error) || $ra_tracklet>=($ra_neocp - $ra_error) ) {
        $ra_match=1;
    }
    if( $dec_tracklet<=($dec_neocp + $dec_error) || $dec_tracklet>=($dec_neocp - $dec_error) ) {
        $dec_match=1;
    }
    if( $pa_tracklet<=($pa_neocp + $pa_error) || $pa_tracklet>=($pa_neocp - $pa_error) ) {
        $pa_match=1;
    }    
    if($v_match && $ra_match && $dec_match && $pa_match) {
        return 1;
    } else { return 0; }
}

# Retrieve a MOPS tracklet from a MOPS instance
sub get_tracklet {
    my $mops_tracklet;
    if($use_mops){
        eval "use PS::MOPS::Instance";
        eval "use PS::MOPS::Tracklet";
    }
    
    my($id)=@_;
    
    # Retrieve a tracklet for a given tracklet ID
}

# Retrieve an ephemeris (table of predictions) for a given ID
sub get_ephemeris {
    my($id)=@_;
}

# Ephemeris data includes the following elements
# date
# ra (decimal)
# dec (decimal)
# velocity (deg/hr)
# position angle
# elongation

# Retrieve fields for comparison with ephemerides
sub get_fields {
    
}

# Retrieve ephemerides for an object 
sub get_ephemerides {
    my ($dbh,$designation)=@_;
    my $sql="SELECT * from ephemerides WHERE ";
}

# Connect to the database and return a DB handle
sub connect_database {   
    my $dbname;
    my $dbhost;
    my $dbport;
    my $dbuser;
    my $dbpass;

    if($local){
        $dbhost="localhost";
        $dbname="neocp";
        $dbuser="root";
        $dbpass="panstar1";
        $dbport="3306";
        
        print "Using local database\n";
    } else {        
        $dbname="neocp";
        $dbhost="mops00.ifa.hawaii.edu";
        $dbport="3306";
        $dbuser="mopsroot";
        $dbpass="panstar1";
        if($db_tunnel){
             $dbhost="localhost";
             $dbname="neocp";
             $dbuser="mopsroot";
             $dbpass="panstar1";
             $dbport="9060";        
         }
    }
    
    my $dbconnect="DBI:mysql:$dbname:$dbhost:$dbport";
    my $dbh=DBI->connect($dbconnect,$dbuser,$dbpass) || die "ERROR: Cannot connect to $dbname.";
    return $dbh;    
}

# Convert calendar time to MJD
sub convert_to_mjd {
    my($day,$month,$year,$hour)=@_;
    my $dayfraction=$hour/24;
    my $mjd=cal2mjd($day,$month,$year,$dayfraction);
    if($mjd) { return $mjd; }
    else { return 0; }
}

1;