//
//  DistanceViewController.m
//  Distance
//
//  Created by Bill Dudney on 11/6/08.
//  Copyright __MyCompanyName__ 2008. All rights reserved.
//
//
//  Licensed with the Apache 2.0 License
//  http://apache.org/licenses/LICENSE-2.0
//

#import "DistanceViewController.h"

@implementation DistanceViewController

@synthesize locationManager;
@synthesize locations;

@synthesize lastUpdate;
@synthesize totalDistance;
@synthesize averageSpeed;

//START:code.distance.viewDidLoad
- (void)viewDidLoad {
  [super viewDidLoad];
  self.locationManager = [[[CLLocationManager alloc] init] autorelease];
  self.locationManager.distanceFilter = 10.0f;
  self.locationManager.delegate = self;
  self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
  [self.locationManager startUpdatingLocation];
  // 32 is a guess of a 'good' number
  self.locations = [NSMutableArray arrayWithCapacity:32];
}
//END:code.distance.viewDidLoad

//START:code.distance.update
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {
  // if we have a valid location, and its within 20 meters then stop
  // updating location, but turn it back on in 60 seconds
  if(newLocation.horizontalAccuracy > 0.0f && 
     newLocation.horizontalAccuracy < 20.0f) {
    if(self.locations.count > 3) {
      [self.locationManager stopUpdatingLocation];
      [self.locationManager performSelector:@selector(startUpdatingLocation) 
                                withObject:nil
                                afterDelay:60.0f];
    }
    [self.locations addObject:newLocation];
    [self updateDisplay];
  }
}
//END:code.distance.update

//START:code.distance.totalDistanceTraveled
- (CLLocationDistance)totalDistanceTraveled {
  CGFloat totalDistanceTraveled = 0.0f;
  CLLocation *oldLocation = nil;
  for(CLLocation *location in self.locations) {
    if(nil == oldLocation) {
      oldLocation = location;
      continue;
    }
    totalDistanceTraveled += fabs([location getDistanceFrom:oldLocation]);
    oldLocation = location;
  }
  return totalDistanceTraveled;
}
//END:code.distance.totalDistanceTraveled

//START:code.distance.timeDelta
- (NSTimeInterval)timeDelta {
  NSDate *first = [(CLLocation *)[self.locations objectAtIndex:0] timestamp];
  NSDate *last = [(CLLocation *)[self.locations lastObject] timestamp];
  return [last timeIntervalSince1970] - [first timeIntervalSince1970];
}
//END:code.distance.timeDelta

//START:code.distance.updateDisplay
- (void)updateDisplay {
  CLLocationDistance distance = [self totalDistanceTraveled];
  totalDistance.text = [NSString stringWithFormat:@"%5.3f", distance];

  NSTimeInterval time = [self timeDelta];
  // don't want to divide by zero
  if(time == 0.0f) {
    averageSpeed.text = @"0.000";
  } else {
    averageSpeed.text = [NSString stringWithFormat:@"%5.3f", distance / time];
  }
  NSDateFormatter *inputFormatter = [[[NSDateFormatter alloc] init] autorelease];
  [inputFormatter setDateFormat:@"HH:mm:ss.SSSS"];
  NSDate *date = [(CLLocation *)[self.locations lastObject] timestamp];
  lastUpdate.text = [inputFormatter stringFromDate:date];
}
//END:code.distance.updateDisplay

- (void)dealloc {
  self.locationManager = nil;
  self.locations = nil;
  self.lastUpdate = nil;
  self.totalDistance = nil;
  self.averageSpeed = nil;
  [super dealloc];
}

@end
