<commit_before>package com.junjunguo.pocketmaps.navigator;

import org.oscim.core.GeoPoint;

import com.graphhopper.android.GHAsyncTask;
import com.graphhopper.routing.util.EdgeFilter;
import com.graphhopper.storage.NodeAccess;
import com.graphhopper.storage.index.QueryResult;
import com.graphhopper.util.Instruction;
import com.graphhopper.util.InstructionList;
import com.junjunguo.pocketmaps.R;
import com.junjunguo.pocketmaps.map.MapHandler;
import com.junjunguo.pocketmaps.map.Navigator;
import com.junjunguo.pocketmaps.util.GeoMath;
import com.junjunguo.pocketmaps.util.LightSensor;
import com.junjunguo.pocketmaps.util.UnitCalculator;

import android.app.Activity;
import android.support.annotation.WorkerThread;
import android.support.annotation.UiThread;
import android.location.Location;
import android.os.AsyncTask.Status;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

public class NaviEngine
{
  /** The DEBUG_SIMULATOR will simulate first generated route on naviStart and trackingStart. **/
  private static final double MAX_WAY_TOLERANCE = GeoMath.DEGREE_PER_METER * 30.0;
  private static final double MAX_WAY_TOLERANCE_METER = 30.0;

  private static final int BEST_NAVI_ZOOM = 18;
  enum UiJob { Nothing, RecalcPath, UpdateInstruction, Finished };
  private UiJob uiJob = UiJob.Nothing;
  private boolean directTargetDir = false;
  NaviVoice naviVoice;
  LightSensor lightSensor;
  boolean naviVoiceSpoken = false;
  private GeoPoint recalcFrom, recalcTo;
  private static NaviEngine instance;
  private Location pos;
  final PointPosData nearestP = new PointPosData(); 
  private boolean active = false;
  private InstructionList instructions;
  private ImageView navtop_image;
  private TextView navtop_curloc;
  private TextView navtop_nextloc;
  private TextView navtop_when;
  private TextView navtop_time;
  private float tiltMult = 1.0f;
  private float tiltMultPos = 1.0f;
  GHAsyncTask<GeoPoint, NaviInstruction, NaviInstruction> naviEngineTask;
  private double partDistanceScaler = 1.0;

  public static NaviEngine getNaviEngine()
  {
    if (instance == null) { instance = new NaviEngine(); }
    return instance;
  }
  
  public boolean isNavigating()
  {
    return active;
  }
  
  public void setNavigating(Activity activity, boolean active)
  {
    this.active = active;
    if (active && lightSensor==null)
    {
      lightSensor = new LightSensor(activity);
    }
    else if ((!active) && lightSensor!=null)
    {
      lightSensor.cleanup(activity);
      lightSensor = null;
    }
    if (naviVoice == null)
    {
      naviVoice = new NaviVoice(activity.getApplicationContext());
    }
    if (active == false)
    {
      MapHandler.getMapHandler().setCustomPointIcon(activity, R.drawable.ic_my_location_dark_24dp);
      if (pos != null)
      {
        GeoPoint curPos = new GeoPoint(pos.getLatitude(), pos.getLongitude());
        MapHandler.getMapHandler().centerPointOnMap(curPos, BEST_NAVI_ZOOM, 0, 0);
      }
      NaviDebugSimulator.getSimu().setSimuRun(false);
      return;
    }
    MapHandler.getMapHandler().setCustomPointIcon(activity, R.drawable.ic_navigation_black_24dp);
    naviVoiceSpoken = false;
    uiJob = UiJob.Nothing;
    initFields(activity);
    instructions = Navigator.getNavigator().getGhResponse().getInstructions();
    resetNewInstruction();
    if (instructions.size() > 0)
    {
      startDebugSimulator(activity, false);
    }
  }
  
  /** This allows to update pathLayer, when instructions is just a line from target to curLoc.
   *  @param directTargetDir True to update pathLayer, join to curPos. **/
  public void setDirectTargetDir(boolean directTargetDir)
  {
    this.directTargetDir = directTargetDir;
  }
  
  public void onUpdateInstructions(InstructionList instructions)
  {
    if (uiJob != UiJob.RecalcPath) { throw new IllegalStateException("Getting instructions but state is not RecalcPath!"); }
    if (!directTargetDir)
    {
      nearestP.checkDirectionOk(pos, instructions.get(0), naviVoice);
    }
    this.instructions = instructions;
    getNewInstruction();
    uiJob = UiJob.UpdateInstruction;
  }
  
  public void startDebugSimulator(Activity activity, boolean fromTracking)
  {
    NaviDebugSimulator.getSimu().startDebugSimulator(activity, instructions, fromTracking);
  }

  private GeoPoint findClosestStreet(GeoPoint fromPos)
  {
    if (MapHandler.getMapHandler().getHopper() == null) { return fromPos; } // Not loaded yet!
    QueryResult pos = MapHandler.getMapHandler().getHopper().getLocationIndex().findClosest(fromPos.getLatitude(), fromPos.getLongitude(), EdgeFilter.ALL_EDGES);
    int n = pos.getClosestEdge().getBaseNode();
    NodeAccess nodeAccess = MapHandler.getMapHandler().getHopper().getGraphHopperStorage().getNodeAccess();
    GeoPoint gp = new GeoPoint(nodeAccess.getLat(n), nodeAccess.getLon(n));
    return gp;
  }
  
  private void initFields(Activity activity)
  {
    if (navtop_image != null) { return; } //TODO: Bug! Delete this line!
    navtop_image = activity.findViewById(R.id.navtop_image);
    navtop_curloc = activity.findViewById(R.id.navtop_curloc);
    navtop_nextloc = activity.findViewById(R.id.navtop_nextloc);
    navtop_when = activity.findViewById(R.id.navtop_when);
    navtop_time = activity.findViewById(R.id.navtop_time);
  }
  
  @UiThread
  public void updatePosition(Activity activity, Location pos)
  {
    if (active == false) { return; }
    if (uiJob == UiJob.RecalcPath) { return; }
    if (this.pos == null) { this.pos = new Location((String)null); }
    this.pos.set(pos);
    GeoPoint curPos = new GeoPoint(pos.getLatitude(), pos.getLongitude());
    GeoPoint newCenter = curPos.destinationPoint(70.0 * tiltMultPos, pos.getBearing());
    MapHandler.getMapHandler().centerPointOnMap(newCenter, BEST_NAVI_ZOOM, 360.0f - pos.getBearing(), 45.0f * tiltMult);
    
    calculatePositionAsync(activity, curPos);
  }

  @UiThread
  private void calculatePositionAsync(Activity activity, GeoPoint curPos)
  {
    if (naviEngineTask == null) { createNaviEngineTask(activity); }
    updateDirectTargetDir(curPos);
    if (naviEngineTask.getStatus() == Status.RUNNING)<commit_msg>Navigation labels not updating #103<commit_after>package com.junjunguo.pocketmaps.navigator;

import org.oscim.core.GeoPoint;

import com.graphhopper.android.GHAsyncTask;
import com.graphhopper.routing.util.EdgeFilter;
import com.graphhopper.storage.NodeAccess;
import com.graphhopper.storage.index.QueryResult;
import com.graphhopper.util.Instruction;
import com.graphhopper.util.InstructionList;
import com.junjunguo.pocketmaps.R;
import com.junjunguo.pocketmaps.map.MapHandler;
import com.junjunguo.pocketmaps.map.Navigator;
import com.junjunguo.pocketmaps.util.GeoMath;
import com.junjunguo.pocketmaps.util.LightSensor;
import com.junjunguo.pocketmaps.util.UnitCalculator;

import android.app.Activity;
import android.support.annotation.WorkerThread;
import android.support.annotation.UiThread;
import android.location.Location;
import android.os.AsyncTask.Status;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

public class NaviEngine
{
  /** The DEBUG_SIMULATOR will simulate first generated route on naviStart and trackingStart. **/
  private static final double MAX_WAY_TOLERANCE = GeoMath.DEGREE_PER_METER * 30.0;
  private static final double MAX_WAY_TOLERANCE_METER = 30.0;

  private static final int BEST_NAVI_ZOOM = 18;
  enum UiJob { Nothing, RecalcPath, UpdateInstruction, Finished };
  private UiJob uiJob = UiJob.Nothing;
  private boolean directTargetDir = false;
  NaviVoice naviVoice;
  LightSensor lightSensor;
  boolean naviVoiceSpoken = false;
  private GeoPoint recalcFrom, recalcTo;
  private static NaviEngine instance;
  private Location pos;
  final PointPosData nearestP = new PointPosData(); 
  private boolean active = false;
  private InstructionList instructions;
  private ImageView navtop_image;
  private TextView navtop_curloc;
  private TextView navtop_nextloc;
  private TextView navtop_when;
  private TextView navtop_time;
  private float tiltMult = 1.0f;
  private float tiltMultPos = 1.0f;
  GHAsyncTask<GeoPoint, NaviInstruction, NaviInstruction> naviEngineTask;
  private double partDistanceScaler = 1.0;

  public static NaviEngine getNaviEngine()
  {
    if (instance == null) { instance = new NaviEngine(); }
    return instance;
  }
  
  public boolean isNavigating()
  {
    return active;
  }
  
  public void setNavigating(Activity activity, boolean active)
  {
    this.active = active;
    if (active && lightSensor==null)
    {
      lightSensor = new LightSensor(activity);
    }
    else if ((!active) && lightSensor!=null)
    {
      lightSensor.cleanup(activity);
      lightSensor = null;
    }
    if (naviVoice == null)
    {
      naviVoice = new NaviVoice(activity.getApplicationContext());
    }
    if (active == false)
    {
      MapHandler.getMapHandler().setCustomPointIcon(activity, R.drawable.ic_my_location_dark_24dp);
      if (pos != null)
      {
        GeoPoint curPos = new GeoPoint(pos.getLatitude(), pos.getLongitude());
        MapHandler.getMapHandler().centerPointOnMap(curPos, BEST_NAVI_ZOOM, 0, 0);
      }
      NaviDebugSimulator.getSimu().setSimuRun(false);
      return;
    }
    MapHandler.getMapHandler().setCustomPointIcon(activity, R.drawable.ic_navigation_black_24dp);
    naviVoiceSpoken = false;
    uiJob = UiJob.Nothing;
    initFields(activity);
    instructions = Navigator.getNavigator().getGhResponse().getInstructions();
    resetNewInstruction();
    if (instructions.size() > 0)
    {
      startDebugSimulator(activity, false);
    }
  }
  
  /** This allows to update pathLayer, when instructions is just a line from target to curLoc.
   *  @param directTargetDir True to update pathLayer, join to curPos. **/
  public void setDirectTargetDir(boolean directTargetDir)
  {
    this.directTargetDir = directTargetDir;
  }
  
  public void onUpdateInstructions(InstructionList instructions)
  {
    if (uiJob != UiJob.RecalcPath) { throw new IllegalStateException("Getting instructions but state is not RecalcPath!"); }
    if (!directTargetDir)
    {
      nearestP.checkDirectionOk(pos, instructions.get(0), naviVoice);
    }
    this.instructions = instructions;
    getNewInstruction();
    uiJob = UiJob.UpdateInstruction;
  }
  
  public void startDebugSimulator(Activity activity, boolean fromTracking)
  {
    NaviDebugSimulator.getSimu().startDebugSimulator(activity, instructions, fromTracking);
  }

  private GeoPoint findClosestStreet(GeoPoint fromPos)
  {
    if (MapHandler.getMapHandler().getHopper() == null) { return fromPos; } // Not loaded yet!
    QueryResult pos = MapHandler.getMapHandler().getHopper().getLocationIndex().findClosest(fromPos.getLatitude(), fromPos.getLongitude(), EdgeFilter.ALL_EDGES);
    int n = pos.getClosestEdge().getBaseNode();
    NodeAccess nodeAccess = MapHandler.getMapHandler().getHopper().getGraphHopperStorage().getNodeAccess();
    GeoPoint gp = new GeoPoint(nodeAccess.getLat(n), nodeAccess.getLon(n));
    return gp;
  }
  
  private void initFields(Activity activity)
  {
    navtop_image = activity.findViewById(R.id.navtop_image);
    navtop_curloc = activity.findViewById(R.id.navtop_curloc);
    navtop_nextloc = activity.findViewById(R.id.navtop_nextloc);
    navtop_when = activity.findViewById(R.id.navtop_when);
    navtop_time = activity.findViewById(R.id.navtop_time);
  }
  
  @UiThread
  public void updatePosition(Activity activity, Location pos)
  {
    if (active == false) { return; }
    if (uiJob == UiJob.RecalcPath) { return; }
    if (this.pos == null) { this.pos = new Location((String)null); }
    this.pos.set(pos);
    GeoPoint curPos = new GeoPoint(pos.getLatitude(), pos.getLongitude());
    GeoPoint newCenter = curPos.destinationPoint(70.0 * tiltMultPos, pos.getBearing());
    MapHandler.getMapHandler().centerPointOnMap(newCenter, BEST_NAVI_ZOOM, 360.0f - pos.getBearing(), 45.0f * tiltMult);
    
    calculatePositionAsync(activity, curPos);
  }

  @UiThread
  private void calculatePositionAsync(Activity activity, GeoPoint curPos)
  {
    if (naviEngineTask == null) { createNaviEngineTask(activity); }
    updateDirectTargetDir(curPos);
    if (naviEngineTask.getStatus() == Status.RUNNING)
{'fraction_non_alphanumeric': 0.10135518948308042, 'fraction_numerical': 0.005436987746490303, 'mean_word_length': 4.39343544857768, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '4335975', 'n_tokens_mistral': 3989, 'n_tokens_neox': 3861, 'n_words': 800}