package org.ka2ddo.yaac;
/*
 * Copyright (C) 2011-2012 Andrew Pavlin, KA2DDO
 * This file is part of the sample plugin for YAAC (Yet Another APRS Client).
 *
 *  YAAC is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  YAAC 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
 *  and GNU Lesser General Public License along with YAAC.  If not,
 *  see <http://www.gnu.org/licenses/>.
 */
import org.ka2ddo.aprs.PositionMessage;
import org.ka2ddo.ax25.AX25Message;
import org.ka2ddo.util.DistanceUnit;
import org.ka2ddo.yaac.ax25.StationState;
import org.ka2ddo.yaac.ax25.TrackerListener;
import org.ka2ddo.yaac.gps.GPSDistributor;
import org.ka2ddo.gps.GpsFix;
import org.ka2ddo.yaac.io.BeaconData;
import org.ka2ddo.yaac.util.LatLongDistance;

/**
 * This sample class provides a means to log to an arbitrary destination all occurrences of
 * position updates for received stations. Note that this is only invoked by the SamplePluginProvider
 * when YAAC is invoked in non-GUI mode.
 *
 * @see SamplePluginProvider
 */
public class SampleVectorCalculator implements TrackerListener {
    /**
     * Called when a new station is initially added to the tracker.
     *
     * @param ss    StationState containing the station's information; the initial Message
     *              will not yet be stored within the StationState object
     * @param index zero-based integer sequence number for this station in the StationTracker
     */
    public void stationAdded(StationState ss, int index) {
        // do nothing, no useful information yet
    }

    /**
     * Called when an existing station is updated with new information in the tracker.
     *
     * @param ss    StationState containing the station's information; the new Message
     *              will not yet be stored within the StationState object
     */
    public void stationUpdated(StationState ss) {
        // do nothing, useful information in the Message
    }

    /**
     * Called when an existing station is deleted from the tracker.
     *
     * @param ss    StationState containing the station's information
     * @param index zero-based integer sequence number for this station in the StationTracker
     */
    public void stationDeleted(StationState ss, int index) {
        // do nothing
    }

    /**
     * Called when a Message is added to the history for a station in the tracker.
     *
     * @param ss    StationState containing the station's information
     * @param index zero-based index of the message added to the StationState object
     * @param msg   APRS Message object being added to the tracker; note that non-APRS packets
     */
    public void messageAdded(StationState ss, int index, AX25Message msg) {
        if (msg instanceof PositionMessage) {
            // get the other station's position
            PositionMessage pm = (PositionMessage)msg;
            double lat2 = pm.decodeLatitude();
            double lon2 = pm.decodeLongitude();

            // get this station's fix
            double lat = 0, lon = 0;
            GpsFix fix = GPSDistributor.getInstance().getCurrentFix();
            if (null != fix && fix.quality.isValid()) {
                lat = fix.latitude;
                lon = fix.longitude;
            } else {
                BeaconData beaconData = YAAC.getBeaconData();
                lat = beaconData.latitude;
                lon = beaconData.longitude;
            }

            // calculate the distance and bearing from my station to the other guy
            DistanceUnit distanceUnit = YAAC.getDistanceUnit();
            double dist = LatLongDistance.computeDistance(lat, lon, lat2, lon2) *
                    distanceUnit.from(DistanceUnit.METER);
            double bearing = LatLongDistance.computeDirection(lat, lon, lat2, lon2);

            // make the report
            String text = "Station " + ss.getIdentifier() + " distance " + (float)dist + ' ' +
                    distanceUnit.toString() + " bearing " + (float)bearing + " degrees";

            //TODO: send the report (improve destination delivery)
            System.out.println(text);
        }
    }

    /**
     * Called when a AX25Message is deleted from the history for a station in the tracker.
     *
     * @param ss    StationState containing the station's information; the AX25Message
     *              will already be removed from the StationState object
     * @param index zero-based index of the message removed from the StationState object
     * @param msg   APRS Message object being removed from the tracker; note that non-APRS packets
     *              that can still be decoded (such as OpenTRAC) will also be passed
     *              here; AX25Frames that cannot be decoded will pass null here
     */
    public void messageDeleted(StationState ss, int index, AX25Message msg) {
        // do nothing
    }
}
