//
//  LocationFinder.m
//  LostClient
//
//  Created by Webster Ross III on 4/2/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "LocationFinder.h"
#import "LostLocation.h"
#import "Constants.h"

static LocationFinder *sharedLocationFinder= nil;

@implementation LocationFinder
@synthesize primaryDelegate, secondaryDelegate, lastLocation, manualLocation, usingManualLocation, currentLocation;

- (id)init{
	if (self = [super init]) {
		locationManager = [[CLLocationManager alloc] init];
		locationManager.delegate = self;
		locationManager.desiredAccuracy = LOCATION_FINDER_DESIRED_ACCURACY;
		locationManager.distanceFilter = LOCATION_FINDER_DISTANCE_FILTER;
		updateCount = 0;
    usingManualLocation = FALSE;
	}
	return self;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
		   fromLocation:(CLLocation *)oldLocation {
	
    NSDate *updateTimeStamp = newLocation.timestamp;
    NSTimeInterval lastUpdate = [updateTimeStamp timeIntervalSinceNow];
	self.lastLocation = currentLocation;
	

    if (abs(lastUpdate) < LOCATION_FINDER_MIN_UPDATE_TIME && !signbit(newLocation.horizontalAccuracy))
    {
        
        if(usingManualLocation)
        {
            //newLocation = [[CLLocation alloc] initWithLatitude:40.81 longitude:-73.95];
            LostLocation *loc = [[LostLocation alloc] init];
            loc.searchLocation = newLocation;
            loc.resultLocation = manualLocation;
            
            self.currentLocation = manualLocation;
            [primaryDelegate locationUpdate:loc]; 
            //[secondaryDelegate locationUpdate:manualLocation]; 
            
            [loc release];
        }
        
        else 
        {
            //newLocation = [[CLLocation alloc] initWithLatitude:40.81 longitude:-73.95];
            updateCount = 0;
            [manager stopUpdatingLocation];
            
            LostLocation *loc = [[LostLocation alloc] init];
            loc.searchLocation = newLocation;
            loc.resultLocation = newLocation;
            
            self.currentLocation = newLocation;
            [primaryDelegate locationUpdate:loc];
            [secondaryDelegate locationUpdate:loc];

            
            [loc release];  
        }
		
    }
	else
	{
		if(updateCount++ == LOCATION_FINDER_MAX_UPDATE_RETRY){
			updateCount = 0;
			[manager stopUpdatingLocation];
			[primaryDelegate locationUpdateError:[NSError errorWithDomain:kCLErrorDomain code:kCLErrorLocationUnknown userInfo:nil]];
      self.currentLocation = nil;
		}
	}	
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
	
	if([error domain] == kCLErrorDomain && [error code] == kCLErrorLocationUnknown) {
		if(updateCount++ == LOCATION_FINDER_MAX_UPDATE_RETRY){
			updateCount = 0;
			[manager stopUpdatingLocation];
			[primaryDelegate locationUpdateError:error];
      self.currentLocation = nil;
		}
	}
	else {
		updateCount = 0;
		[manager stopUpdatingLocation];
		[primaryDelegate locationUpdateError:error];
    self.currentLocation = nil;
	}
}

- (void) findCurrentLocation {
  
    [locationManager startUpdatingLocation];
}

- (double)distanceMoved {
  
  if(lastLocation != nil && currentLocation != nil)
  {
    return [lastLocation getDistanceFrom:currentLocation];
  }
  
  return -1;
}

+ (LocationFinder *)sharedInstance {
    @synchronized(self) {
        if (sharedLocationFinder == nil) {
            [[self alloc] init];
        }
    }
    return sharedLocationFinder;
}

+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (sharedLocationFinder == nil) {
            sharedLocationFinder = [super allocWithZone:zone];
            return sharedLocationFinder;
        }
    }
    return nil;
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)retain {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;
}

- (void)release {	
}

- (id)autorelease {
	return self;
}

@end
