<commit_before>/**
 * Created by andreas on 04.05.14.
 */
avnav.provide('avnav.nav.NavObject');
avnav.provide('avnav.nav.NavEvent');
avnav.provide('avnav.nav.NavEventSource');

/**
 * the navevent type
 * @enum {number}
 */
avnav.nav.NavEventType={
    GPS:0,
    AIS:1,
    TRACK:2,
    NAV:3,
    ROUTE: 4
};

/**
 * a definition of the source that caused an event
 * to avoid endless loops
 * @enum {number}
 */
avnav.nav.NavEventSource={
    NAV:0,
    GUI:1,
    MAP:2
};

/**
 *
 * @param {avnav.nav.NavEventType} type
 * @param {Array.<string>} changedNames the display names that have changed data
 * @param {avnav.nav.NavEventSource} source
 * @param {avnav.nav.NavObject} navobject
 * @constructor
 */
avnav.nav.NavEvent=function(type,changedNames,source,navobject){
    /**
     * @type {avnav.nav.NavEventType}
     */
    this.type=type;
    /**
     * the list of changed display elements
     * @type {Array.<string>}
     */
    this.changedNames=changedNames;
    /**
     * @type {avnav.nav.NavEventSource}
     */
    this.source=source;
    /**
     * @type {avnav.nav.NavObject}
     */
    this.navobject=navobject;
};

avnav.nav.NavEvent.EVENT_TYPE="navevent";

/**
 *
 * @param {avnav.util.PropertyHandler} propertyHandler
 * @constructor
 */
avnav.nav.NavObject=function(propertyHandler){
    /** @private */
    this.propertyHandler=propertyHandler;

    /**
     * @private
     * @type {avnav.util.Formatter}
     */
    this.formatter=new avnav.util.Formatter();
    /**
     * a map from the display names to the function that provides the data
     * @type {{}}
     * @private
     */
    this.valueMap={};
    /** @type {avnav.nav.GpsData}
     * @private
     */
    this.gpsdata=new avnav.nav.GpsData(propertyHandler,this);
    /**
     * @private
     * @type {avnav.nav.TrackData}
     */
    this.trackHandler=new avnav.nav.TrackData(propertyHandler,this);

    this.aisHandler=new avnav.nav.AisData(propertyHandler,this);
    this.routeHandler=new avnav.nav.RouteData(propertyHandler,this);
    /**
     * @private
     * @type {avnav.nav.navdata.Point}
     */
    this.maplatlon=new avnav.nav.navdata.Point(0,0);


    /**
     * our computed data...
     * @type {{centerCourse: number, centerDistance: number, markerCourse: number, markerDistance: number}}
     */
    this.data={
        centerCourse:0,
        centerDistance:0,
        centerMarkerCourse:0,
        centerMarkerDistance:0,
        markerCourse:0,
        markerDistance:0,
        /**
         * @type {Date}
         */
        markerEta:null,
        markerLatlon:new avnav.nav.navdata.Point(0,0),
        routeName: undefined,
        routeNumPoints: 0,
        routeLen: 0,
        routeRemain: 0,
        routeEta: null
    };
    this.formattedValues={
        markerEta:"none",
        markerCourse:"--",
        markerDistance:"--",
        markerPosition:"none",
        centerCourse:"--",
        centerDistance:"--",
        centerMarkerCourse:"--",
        centerMarkerDistance:"--",
        centerPosition:"--",
        routeName: "default",
        routeNumPoints: "--",
        routeLen: "--",
        routeRemain: "--",
        routeEta: "--"
    };
    for (var k in this.formattedValues){
        this.registerValueProvider(k,this,this.getFormattedNavValue);
    }
};

/**
 * compute the raw and formtted valued
 * @private
 */
avnav.nav.NavObject.prototype.computeValues=function(){
    var gps=this.gpsdata.getGpsData();
    //copy the marker to data to make it available extern
    this.data.markerLatlon=this.routeHandler.getRouteData().to;
    var vmgapp=0;
    if (gps.valid){
        var markerdst=avnav.nav.NavCompute.computeDistance(gps,this.data.markerLatlon);
        this.data.markerCourse=markerdst.course;
        this.data.markerDistance=markerdst.dtsnm;
        if (gps.rtime && (Math.abs(markerdst.course-gps.course) <= 85)) {
            //TODO: is this really correct for VMG?
            vmgapp = gps.speed * Math.cos(Math.PI / 180 * (gps.course - markerdst.course));
            //vmgapp is in kn
            var targettime = gps.rtime.getTime();
            if (vmgapp > 0) {
            targettime += this.data.markerDistance / vmgapp * 3600 * 1000; //time in ms
            var targetDate = new Date(Math.round(targettime));
            this.data.markerEta = targetDate;
            }
            else {
                this.data.markerEta=null;
            }

        }
        else  this.data.markerEta=null;
        var centerdst=avnav.nav.NavCompute.computeDistance(gps,this.maplatlon);
        this.data.centerCourse=centerdst.course;
        this.data.centerDistance=centerdst.dtsnm;
    }
    else{
        this.data.centerCourse=0;
        this.data.centerDistance=0;
        this.data.markerCourse=0;
        this.data.markerDistance=0;
        this.data.markerEta=null;
    }

    //distance between marker and center
    var mcdst=avnav.nav.NavCompute.computeDistance(this.data.markerLatlon,this.maplatlon);
    this.data.centerMarkerCourse=mcdst.course;
    this.data.centerMarkerDistance=mcdst.dtsnm;
    //route data
    var route=this.routeHandler.getCurrentRoute();
    this.data.routeName=route.name;
    this.data.routeNumPoints=route.points.length;
    this.data.routeLen=this.routeHandler.computeLength(0);
    this.data.routeRemain=this.routeHandler.computeLength(-1)+this.data.markerDistance;
    var routetime = gps.rtime.getTime();
    if (vmgapp > 0) {
        routetime += this.data.routeRemain / vmgapp * 3600 * 1000; //time in ms
        var routeDate = new Date(Math.round(routetime));
        this.data.routeEta = routeDate;
    }
    else {
        this.data.routeEta=undefined;
    }

    //now create text values
    this.formattedValues.markerEta=(this.data.markerEta)?
        this.formatter.formatTime(this.data.markerEta):"--:--:--";
    this.formattedValues.markerCourse=this.formatter.formatDecimal(
        this.data.markerCourse,3,0
    );
    this.formattedValues.markerDistance=this.formatter.formatDecimal(
        this.data.markerDistance,3,1
    );
    this.formattedValues.markerPosition=this.formatter.formatLonLats(<commit_msg>be robust against no gps time<commit_after>/**
 * Created by andreas on 04.05.14.
 */
avnav.provide('avnav.nav.NavObject');
avnav.provide('avnav.nav.NavEvent');
avnav.provide('avnav.nav.NavEventSource');

/**
 * the navevent type
 * @enum {number}
 */
avnav.nav.NavEventType={
    GPS:0,
    AIS:1,
    TRACK:2,
    NAV:3,
    ROUTE: 4
};

/**
 * a definition of the source that caused an event
 * to avoid endless loops
 * @enum {number}
 */
avnav.nav.NavEventSource={
    NAV:0,
    GUI:1,
    MAP:2
};

/**
 *
 * @param {avnav.nav.NavEventType} type
 * @param {Array.<string>} changedNames the display names that have changed data
 * @param {avnav.nav.NavEventSource} source
 * @param {avnav.nav.NavObject} navobject
 * @constructor
 */
avnav.nav.NavEvent=function(type,changedNames,source,navobject){
    /**
     * @type {avnav.nav.NavEventType}
     */
    this.type=type;
    /**
     * the list of changed display elements
     * @type {Array.<string>}
     */
    this.changedNames=changedNames;
    /**
     * @type {avnav.nav.NavEventSource}
     */
    this.source=source;
    /**
     * @type {avnav.nav.NavObject}
     */
    this.navobject=navobject;
};

avnav.nav.NavEvent.EVENT_TYPE="navevent";

/**
 *
 * @param {avnav.util.PropertyHandler} propertyHandler
 * @constructor
 */
avnav.nav.NavObject=function(propertyHandler){
    /** @private */
    this.propertyHandler=propertyHandler;

    /**
     * @private
     * @type {avnav.util.Formatter}
     */
    this.formatter=new avnav.util.Formatter();
    /**
     * a map from the display names to the function that provides the data
     * @type {{}}
     * @private
     */
    this.valueMap={};
    /** @type {avnav.nav.GpsData}
     * @private
     */
    this.gpsdata=new avnav.nav.GpsData(propertyHandler,this);
    /**
     * @private
     * @type {avnav.nav.TrackData}
     */
    this.trackHandler=new avnav.nav.TrackData(propertyHandler,this);

    this.aisHandler=new avnav.nav.AisData(propertyHandler,this);
    this.routeHandler=new avnav.nav.RouteData(propertyHandler,this);
    /**
     * @private
     * @type {avnav.nav.navdata.Point}
     */
    this.maplatlon=new avnav.nav.navdata.Point(0,0);


    /**
     * our computed data...
     * @type {{centerCourse: number, centerDistance: number, markerCourse: number, markerDistance: number}}
     */
    this.data={
        centerCourse:0,
        centerDistance:0,
        centerMarkerCourse:0,
        centerMarkerDistance:0,
        markerCourse:0,
        markerDistance:0,
        /**
         * @type {Date}
         */
        markerEta:null,
        markerLatlon:new avnav.nav.navdata.Point(0,0),
        routeName: undefined,
        routeNumPoints: 0,
        routeLen: 0,
        routeRemain: 0,
        routeEta: null
    };
    this.formattedValues={
        markerEta:"none",
        markerCourse:"--",
        markerDistance:"--",
        markerPosition:"none",
        centerCourse:"--",
        centerDistance:"--",
        centerMarkerCourse:"--",
        centerMarkerDistance:"--",
        centerPosition:"--",
        routeName: "default",
        routeNumPoints: "--",
        routeLen: "--",
        routeRemain: "--",
        routeEta: "--"
    };
    for (var k in this.formattedValues){
        this.registerValueProvider(k,this,this.getFormattedNavValue);
    }
};

/**
 * compute the raw and formtted valued
 * @private
 */
avnav.nav.NavObject.prototype.computeValues=function(){
    var gps=this.gpsdata.getGpsData();
    //copy the marker to data to make it available extern
    this.data.markerLatlon=this.routeHandler.getRouteData().to;
    var vmgapp=0;
    if (gps.valid){
        var markerdst=avnav.nav.NavCompute.computeDistance(gps,this.data.markerLatlon);
        this.data.markerCourse=markerdst.course;
        this.data.markerDistance=markerdst.dtsnm;
        if (gps.rtime && (Math.abs(markerdst.course-gps.course) <= 85)) {
            //TODO: is this really correct for VMG?
            vmgapp = gps.speed * Math.cos(Math.PI / 180 * (gps.course - markerdst.course));
            //vmgapp is in kn
            var targettime = gps.rtime.getTime();
            if (vmgapp > 0) {
            targettime += this.data.markerDistance / vmgapp * 3600 * 1000; //time in ms
            var targetDate = new Date(Math.round(targettime));
            this.data.markerEta = targetDate;
            }
            else {
                this.data.markerEta=null;
            }

        }
        else  this.data.markerEta=null;
        var centerdst=avnav.nav.NavCompute.computeDistance(gps,this.maplatlon);
        this.data.centerCourse=centerdst.course;
        this.data.centerDistance=centerdst.dtsnm;
    }
    else{
        this.data.centerCourse=0;
        this.data.centerDistance=0;
        this.data.markerCourse=0;
        this.data.markerDistance=0;
        this.data.markerEta=null;
    }

    //distance between marker and center
    var mcdst=avnav.nav.NavCompute.computeDistance(this.data.markerLatlon,this.maplatlon);
    this.data.centerMarkerCourse=mcdst.course;
    this.data.centerMarkerDistance=mcdst.dtsnm;
    //route data
    var route=this.routeHandler.getCurrentRoute();
    this.data.routeName=route.name;
    this.data.routeNumPoints=route.points.length;
    this.data.routeLen=this.routeHandler.computeLength(0);
    this.data.routeRemain=this.routeHandler.computeLength(-1)+this.data.markerDistance;
    var routetime=0;
    if (gps.rtime) routetime= gps.rtime.getTime();
    if (vmgapp > 0 && routetime != 0) {
        routetime += this.data.routeRemain / vmgapp * 3600 * 1000; //time in ms
        var routeDate = new Date(Math.round(routetime));
        this.data.routeEta = routeDate;
    }
    else {
        this.data.routeEta=undefined;
    }

    //now create text values
    this.formattedValues.markerEta=(this.data.markerEta)?
        this.formatter.formatTime(this.data.markerEta):"--:--:--";
    this.formattedValues.markerCourse=this.formatter.formatDecimal(
        this.data.markerCourse,3,0
    );
    this.formattedValues.markerDistance=this.formatter.formatDecimal(
        this.data.markerDistance,3,1
    );
    this.formattedValues.markerPosition=this.formatter.formatLonLats(
{'fraction_non_alphanumeric': 0.13734079662529408, 'fraction_numerical': 0.01005921959925367, 'mean_word_length': 2.529344403091898, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6403035', 'n_tokens_mistral': 4112, 'n_tokens_neox': 3989, 'n_words': 643}