<commit_before>#import "SearchVC.h"
#import "CompassView.h"

#include "../../geometry/angles.hpp"
#include "../../geometry/distance_on_sphere.hpp"
#include "../../indexer/mercator.hpp"
#include "../../map/framework.hpp"
#include "../../search/result.hpp"

SearchVC * g_searchVC = nil;
SearchF g_searchF;
ShowRectF g_showRectF;
GetViewportCenterF g_getViewportCenterF;
volatile int g_queryId = 0;

@interface Wrapper : NSObject
{ // HACK: ownership is taken by the "get" method caller
  search::Result * m_result;
}
- (id)initWithResult:(search::Result const &) res;
- (search::Result const *)get;
@end

@implementation Wrapper

- (id)initWithResult:(search::Result const &) res
{
  if ((self = [super init]))
    m_result = new search::Result(res);
  return self;
}

- (void)dealloc
{
  delete m_result;
  [super dealloc];
}

- (search::Result const *)get
{
  return m_result;
}
@end

static void OnSearchResultCallback(search::Result const & res, int queryId)
{
  if (g_searchVC && queryId == g_queryId)
  {
    Wrapper * w = [[Wrapper alloc] initWithResult:res];
    [g_searchVC performSelectorOnMainThread:@selector(addResult:)
                                 withObject:w
                              waitUntilDone:NO];
    [w release];
  }
}

@implementation SearchVC

- (id)initWithSearchFunc:(SearchF)s andShowRectFunc:(ShowRectF)r 
  andGetViewportCenterFunc:(GetViewportCenterF)c
{
  if ((self = [super initWithNibName:nil bundle:nil]))
  {
    g_searchF = s;
    g_showRectF = r;
    g_getViewportCenterF = c;
    m_locationManager = [[CLLocationManager alloc] init];
    m_locationManager.delegate = self;
    // filter out unnecessary events
    m_locationManager.headingFilter = 3;
    m_locationManager.distanceFilter = 1.0;
    m_isRadarEnabled = false;
  }
  return self;
}

- (void)clearResults
{
  m_results.clear();
}

- (void)dealloc
{
  [m_locationManager release];
  g_searchVC = nil;
  [self clearResults];
  [super dealloc];
}

- (void)onRadarButtonClick:(id)button
{
  m_isRadarEnabled = !m_isRadarEnabled;
  self.navigationItem.rightBarButtonItem.image = m_isRadarEnabled ? 
      [UIImage imageNamed:@"location-selected.png"] :
      [UIImage imageNamed:@"location.png"];
  if (m_isRadarEnabled)
  {
    [m_locationManager startUpdatingLocation];
    if ([CLLocationManager headingAvailable])
      [m_locationManager startUpdatingHeading];
  }
  else
  {
    if ([CLLocationManager headingAvailable])
      [m_locationManager stopUpdatingHeading];
    [m_locationManager stopUpdatingLocation];
    [(UITableView *)self.view reloadData];
  }
}

- (void)loadView
{
  UITableView * tableView = [[[UITableView alloc] init] autorelease];
  tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  tableView.delegate = self;
  tableView.dataSource = self;
  self.view = tableView;
  self.title = @"Search";

  UISearchBar * searchBar = [[[UISearchBar alloc] init] autorelease];
  searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  self.navigationItem.titleView = searchBar;
  [searchBar sizeToFit];
  searchBar.delegate = self;
  
  // add radar mode button
  UIImage * img = m_isRadarEnabled ? [UIImage imageNamed:@"location-selected.png"] : [UIImage imageNamed:@"location.png"];
  self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithImage:img
                                                                            style:UIBarButtonItemStylePlain
                                                                           target:self
                                                                           action:@selector(onRadarButtonClick:)] autorelease];
}

- (void)viewDidLoad
{
  g_searchVC = self;
}

- (void)viewDidUnload
{
  [m_locationManager stopUpdatingHeading];
  [m_locationManager stopUpdatingLocation];
  g_searchVC = nil;
}

- (void)viewWillDisappear:(BOOL)animated
{
  // hide keyboard immediately
  [self.navigationItem.titleView resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)sender textDidChange:(NSString *)searchText
{
  [self clearResults];
  [(UITableView *)self.view reloadData];
  ++g_queryId;

  // show active search indicator
  //  self.navigationItem.rightBarButtonItem.customView = [[[UIActivityIndicatorView alloc]
  //      initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray] autorelease];

  if ([searchText length] > 0)
  {
    g_searchF([[searchText precomposedStringWithCompatibilityMapping] UTF8String],
              bind(&OnSearchResultCallback, _1, g_queryId));
  }
}

- (double)calculateAngle:(m2::PointD const &)pt
{
  if (m_isRadarEnabled)
  {
    CLLocation * loc = m_locationManager.location;
    if (loc)
    {
      double angle = ang::AngleTo(m2::PointD(MercatorBounds::LonToX(loc.coordinate.longitude),
                                   MercatorBounds::LatToY(loc.coordinate.latitude)), pt);
      CLHeading * h = m_locationManager.heading;
      if (h)
      {
        CLLocationDirection northDeg = h.trueHeading;
        if (northDeg < 0.)
          northDeg = h.magneticHeading;
        double const northRad = northDeg / 180. * math::pi;
        angle -= northRad;
      }
      return angle;
    }
  }
  m2::PointD const center = g_getViewportCenterF();
  return ang::AngleTo(center, pt);
}

- (double)calculateDistance:(m2::PointD const &)pt
{
  double const ptLat = MercatorBounds::YToLat(pt.y);
  double const ptLon = MercatorBounds::XToLon(pt.x);
  if (m_isRadarEnabled)
  {
    CLLocation * loc = m_locationManager.location;
    if (loc)
      return ms::DistanceOnEarth(loc.coordinate.latitude, loc.coordinate.longitude,
                                          ptLat, ptLon);
  }
  m2::PointD const center = g_getViewportCenterF();
  return ms::DistanceOnEarth(MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x),
                             ptLat, ptLon);
}

- (void)updateCellAngle:(UITableViewCell *)cell withIndex:(NSUInteger)index
{
  double const angle = [self calculateAngle:m_results[index].GetFeatureCenter()];  
  CompassView * compass = (CompassView *)cell.accessoryView;
  compass.angle = angle;
}

- (void)updateCellDistance:(UITableViewCell *)cell withIndex:(NSUInteger)index<commit_msg>[ios] Fixed Radar mode angle<commit_after>#import "SearchVC.h"
#import "CompassView.h"

#include "../../geometry/angles.hpp"
#include "../../geometry/distance_on_sphere.hpp"
#include "../../indexer/mercator.hpp"
#include "../../map/framework.hpp"
#include "../../search/result.hpp"

SearchVC * g_searchVC = nil;
SearchF g_searchF;
ShowRectF g_showRectF;
GetViewportCenterF g_getViewportCenterF;
volatile int g_queryId = 0;

@interface Wrapper : NSObject
{ // HACK: ownership is taken by the "get" method caller
  search::Result * m_result;
}
- (id)initWithResult:(search::Result const &) res;
- (search::Result const *)get;
@end

@implementation Wrapper

- (id)initWithResult:(search::Result const &) res
{
  if ((self = [super init]))
    m_result = new search::Result(res);
  return self;
}

- (void)dealloc
{
  delete m_result;
  [super dealloc];
}

- (search::Result const *)get
{
  return m_result;
}
@end

static void OnSearchResultCallback(search::Result const & res, int queryId)
{
  if (g_searchVC && queryId == g_queryId)
  {
    Wrapper * w = [[Wrapper alloc] initWithResult:res];
    [g_searchVC performSelectorOnMainThread:@selector(addResult:)
                                 withObject:w
                              waitUntilDone:NO];
    [w release];
  }
}

@implementation SearchVC

- (id)initWithSearchFunc:(SearchF)s andShowRectFunc:(ShowRectF)r 
  andGetViewportCenterFunc:(GetViewportCenterF)c
{
  if ((self = [super initWithNibName:nil bundle:nil]))
  {
    g_searchF = s;
    g_showRectF = r;
    g_getViewportCenterF = c;
    m_locationManager = [[CLLocationManager alloc] init];
    m_locationManager.delegate = self;
    // filter out unnecessary events
    m_locationManager.headingFilter = 3;
    m_locationManager.distanceFilter = 1.0;
    m_isRadarEnabled = false;
  }
  return self;
}

- (void)clearResults
{
  m_results.clear();
}

- (void)dealloc
{
  [m_locationManager release];
  g_searchVC = nil;
  [self clearResults];
  [super dealloc];
}

- (void)onRadarButtonClick:(id)button
{
  m_isRadarEnabled = !m_isRadarEnabled;
  self.navigationItem.rightBarButtonItem.image = m_isRadarEnabled ? 
      [UIImage imageNamed:@"location-selected.png"] :
      [UIImage imageNamed:@"location.png"];
  if (m_isRadarEnabled)
  {
    [m_locationManager startUpdatingLocation];
    if ([CLLocationManager headingAvailable])
      [m_locationManager startUpdatingHeading];
  }
  else
  {
    if ([CLLocationManager headingAvailable])
      [m_locationManager stopUpdatingHeading];
    [m_locationManager stopUpdatingLocation];
    [(UITableView *)self.view reloadData];
  }
}

- (void)loadView
{
  UITableView * tableView = [[[UITableView alloc] init] autorelease];
  tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  tableView.delegate = self;
  tableView.dataSource = self;
  self.view = tableView;
  self.title = @"Search";

  UISearchBar * searchBar = [[[UISearchBar alloc] init] autorelease];
  searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  self.navigationItem.titleView = searchBar;
  [searchBar sizeToFit];
  searchBar.delegate = self;
  
  // add radar mode button
  UIImage * img = m_isRadarEnabled ? [UIImage imageNamed:@"location-selected.png"] : [UIImage imageNamed:@"location.png"];
  self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithImage:img
                                                                            style:UIBarButtonItemStylePlain
                                                                           target:self
                                                                           action:@selector(onRadarButtonClick:)] autorelease];
}

- (void)viewDidLoad
{
  g_searchVC = self;
}

- (void)viewDidUnload
{
  [m_locationManager stopUpdatingHeading];
  [m_locationManager stopUpdatingLocation];
  g_searchVC = nil;
}

- (void)viewWillDisappear:(BOOL)animated
{
  // hide keyboard immediately
  [self.navigationItem.titleView resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)sender textDidChange:(NSString *)searchText
{
  [self clearResults];
  [(UITableView *)self.view reloadData];
  ++g_queryId;

  // show active search indicator
  //  self.navigationItem.rightBarButtonItem.customView = [[[UIActivityIndicatorView alloc]
  //      initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray] autorelease];

  if ([searchText length] > 0)
  {
    g_searchF([[searchText precomposedStringWithCompatibilityMapping] UTF8String],
              bind(&OnSearchResultCallback, _1, g_queryId));
  }
}

- (double)calculateAngle:(m2::PointD const &)pt
{
  if (m_isRadarEnabled)
  {
    CLLocation * loc = m_locationManager.location;
    if (loc)
    {
      double angle = ang::AngleTo(m2::PointD(MercatorBounds::LonToX(loc.coordinate.longitude),
                                             MercatorBounds::LatToY(loc.coordinate.latitude)), pt);
      CLHeading * h = m_locationManager.heading;
      if (h)
      {
        CLLocationDirection northDeg = h.trueHeading;
        if (northDeg < 0.)
          northDeg = h.magneticHeading;
        double const northRad = northDeg / 180. * math::pi;
        angle += northRad;
      }
      return angle;
    }
  }
  
  m2::PointD const center = g_getViewportCenterF();
  return ang::AngleTo(center, pt);
}

- (double)calculateDistance:(m2::PointD const &)pt
{
  double const ptLat = MercatorBounds::YToLat(pt.y);
  double const ptLon = MercatorBounds::XToLon(pt.x);
  if (m_isRadarEnabled)
  {
    CLLocation * loc = m_locationManager.location;
    if (loc)
      return ms::DistanceOnEarth(loc.coordinate.latitude, loc.coordinate.longitude,
                                          ptLat, ptLon);
  }
  m2::PointD const center = g_getViewportCenterF();
  return ms::DistanceOnEarth(MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x),
                             ptLat, ptLon);
}

- (void)updateCellAngle:(UITableViewCell *)cell withIndex:(NSUInteger)index
{
  double const angle = [self calculateAngle:m_results[index].GetFeatureCenter()];  
  CompassView * compass = (CompassView *)cell.accessoryView;
  compass.angle = angle;
}

- (void)updateCellDistance:(UITableViewCell *)cell withIndex:(NSUInteger)index
{'fraction_non_alphanumeric': 0.11612697399904291, 'fraction_numerical': 0.002552241186792152, 'mean_word_length': 3.337253545485991, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 27, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2245750', 'n_tokens_mistral': 4060, 'n_tokens_neox': 3917, 'n_words': 725}