//
//  DiscoveryContoller.m
//  TagDemo
//
//  Created by jcassidy on 10-11-16.
//  Copyright 2010 Visible Assets Inc. All rights reserved.
//

#import "DiscoveryViewController.h"
#import "Tag.h"
#import "TagDemoAppDelegate.h"
#import "AudioToolBox/AudioServices.h"


@implementation DiscoveryViewController

// ***************************************************************
// *                                                             
// * initWithNibName =  nib loaded from bundle, perform initialization
// *
// ***************************************************************

- (id) initWithNibName:(NSString *) nibNameOrNil bundle:(NSBundle *) nibBundleOrNil 
{
    if( ( self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil] ) ) {
		[self setTitle:@"Discovery"];
    }
    return self;
}


/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

// ***************************************************************
// *                                                             
// * didReceiveMemoryWarning =  low on memory, clean up any unneeded allocations
// *
// ***************************************************************

- (void) didReceiveMemoryWarning 
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

// ***************************************************************
// *                                                             
// * viewDidUnload =  view is unloaded, release any locally added subviews
// *
// ***************************************************************

- (void) viewDidUnload 
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

// ***************************************************************
// *                                                             
// * dealloc =  release local allocations
// *
// ***************************************************************

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

// ***************************************************************
// *                                                             
// * discoverTag =  perform one discovery operation 
// *
// * Note: for continuous discovery, perform in a separate thread (see ping)
// *                                                             
// ***************************************************************

- (void) discoverTag:(id) sender
{
	UIAlertView	*alert;
	Tag			*tag;
	long		tagID;	
	BaseStation *baseStation;
	Timer		*timer;
	
	// require a reference to a basestation for tag communications
	baseStation = [(TagDemoAppDelegate *) [[UIApplication sharedApplication]  delegate] baseStation];
	
	// do a sanity check on the basestation - can't communicate if not connected
	if( ![baseStation isConnected] ) {
		alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Basestation not found" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
		[alert show];
		[alert release];
		return;
	}
	
	// clear old tag id
	[discoveryTextField setText:@""];

	// create a timer object to use to perform discovery attempts for a 
	// specified amount of time
	timer = [[Timer alloc] init];
	
	// create a tag	object and set it's basestation reference so it can communicate with real tags
	tag = [[Tag alloc] init];
	[tag setBaseStation:baseStation];
	
	// set batchmode to YES, meaning that TagLib won't do a wakeup transmission at the start
	// of each discovery sequence, this requires us to do the initial wakeup transmission
	// also set the number of discovery retries to 1, as we will be managing the discovery retries
	// by time
	[tag setBatchMode:YES];
	[tag wakeupTags];
	[tag setMaxRetransmissions:1];
	
	// discover for 2 seconds or until a tag is found 
	[timer setDuration:2.0];
	tagID = 0;
	while( ![timer timeout] && tagID == 0 ) 
		tagID = [tag discoverTagBySubnetID:0L];
	
	// discovery attempt over, was a tag found?
	if( tagID > 0 ) {
		// beep and present discovered tag ID
		[self beep];
		[discoveryTextField setText:[NSString stringWithFormat:@"%ld", tagID]];
		
		// since a valid tag id was found, enable the ping switch
		[pingSwitch setEnabled:YES];
	}
	else{
		// no valid tag found, can't ping anything
		[pingSwitch setEnabled:NO];
	}

	// all done with timer, refresh view
	[timer release];
	[self performSelectorOnMainThread: @selector(refreshView) withObject:nil waitUntilDone:NO];
}

// ***************************************************************
// *                                                             
// * pingTag =  perform continuous ping operation in separate thread
// *
// ***************************************************************

- (void) pingTag:(id) sender
{
	UIAlertView *alert;
	BaseStation *baseStation;
	long		tagID;
	
	baseStation = [(TagDemoAppDelegate *) [[UIApplication sharedApplication]  delegate] baseStation];
	
	if( [sender isOn] ) {
		// ensure that ping thread isn't started twice
		if( pingRunFlag )
			return;
		
		// ensure connected to basestation
		if( ![baseStation isConnected] ) {
			alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Basestation not found" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
			[alert show];
			[alert release];
			[sender setOn:NO animated:YES];
			return;
		}
		
		// run ping thread
		tagID = [[discoveryTextField text] intValue];
		pingThread = [[PingThread alloc] init:self tagID:tagID];
		[pingThread start];
		pingRunFlag = YES;
		[self beep];
		
		// can't discover while pinging, so disable discover button
		[discoveryButton setEnabled:NO];
	}
	else{
		if( !pingRunFlag )
			return;
		
		//stop ping thread
		[pingThread stop];
		while( ![pingThread isShutdown] );
		[pingThread release];
		pingRunFlag = NO;
		
		// re-enable discover button now that pinging is done
		[discoveryButton setEnabled:YES];
	}
}

// ***************************************************************
// *                                                             
// * tagPinged =  called by ping thread when a tag has been pinged                    
// *                                                             
// ***************************************************************

- (void) tagPinged:(Tag *) tag
{
	[pingCountLabel setText:[NSString stringWithFormat:@"%d", pingCount++]];
	
	[self performSelectorOnMainThread: @selector(refreshView) withObject:nil waitUntilDone:NO];
	[self beep];
}

// ***************************************************************
// *                                                             
// * refreshView =  update table                     
// *                                                             
// ***************************************************************

- (void) refreshView
{
	[discoveryTextField setNeedsDisplay];
	[pingCountLabel setNeedsDisplay];
	[discoveryButton setNeedsDisplay];
}

// ***************************************************************
// *                                                             
// * beep =  produce beep                    
// *                                                             
// ***************************************************************

- (void) beep
{
	NSString		*path;
	SystemSoundID	soundID;
	NSURL			*filePath;
	
	path = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"Ping.aiff"];
	filePath = [NSURL fileURLWithPath:path isDirectory:NO];
	AudioServicesCreateSystemSoundID( (CFURLRef) filePath, &soundID );
	AudioServicesPlaySystemSound( soundID );
}


@end
