//
//  PathologicalPrimeCounterViewController.m
//  PathologicalPrimeCounter
//
//  Created by Chris Adamson on 10/12/08.
//  Copyright Subsequently and Furthermore, Inc. 2008. All rights reserved.
//
//
//  Licensed with the Apache 2.0 License
//  http://apache.org/licenses/LICENSE-2.0
//


#import "PathologicalPrimeCounterViewController.h"

@implementation PathologicalPrimeCounterViewController



/*
// Override initWithNibName:bundle: to load the view using a nib file then perform additional customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically.
- (void)loadView {
}
*/


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


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}


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

/* WARNING: PATHOLOGICAL CODE
   LEAKS ONE NSString ON EVERY CALL
*/
//START:code.PathologicalPrimeCounter.appendtoprimearea
- (void) appendPrimeToPrimeArea: (int) aPrime {
	NSString *primeString = [[NSString alloc] initWithFormat: @"%d ", aPrime];
	primesView.text = [primesView.text stringByAppendingString: primeString];
}
//END:code.PathologicalPrimeCounter.appendtoprimearea


/* THIS IS THE CORRECT VERSION OF THIS METHOD
 */
- (void) appendPrime: (int) aPrime
	 toMutableString: (NSMutableString*) mutableString {
	NSString *primeString = [[NSString alloc] initWithFormat: @"%d ", aPrime];
	[mutableString appendString: primeString];
	[primeString release];
}

/* WARNING: PATHOLOGICAL CODE
   THIS LEAKS MEMORY BECAUSE IT DOES NOT RELEASE THE STRING IT CREATES
//START:code.PathologicalPrimeCounter.appendprimetomutablestring
- (void) appendPrime: (int) aPrime
		toMutableString: (NSMutableString*) mutableString {
	NSString *primeString = [[NSString alloc] initWithFormat: @"%d ", aPrime];
	[mutableString appendString: primeString];
}
//END:code.PathologicalPrimeCounter.appendprimetomutablestring
 */


/* THIS IS THE FINAL VERSION OF THIS METHOD. 
 */
- (void) countPrimesToSelectedValue {
	int maxPrime = [countToField.text intValue];
	if (maxPrime < 1)
		return;
	// for each int up to maxPrime, check every divisor up to
	// maxPrime/2+1.  there are more efficient prime counters,
	// but this is easy to understand
//START:code.PathologicalPrimeCounter.callappendprimetomutablestring
	NSMutableString *mutableString =
		[[NSMutableString alloc] initWithCapacity: maxPrime * 5];
	for (int i=2; i<maxPrime; i++) {
		int maxDivisor = i/2 + 1;
		BOOL isPrime = YES;
		for (int j=2; j<maxDivisor; j++) {
			if (i%j == 0) {
				// NSLog (@"%d is not prime, divisible by %d", i, j);
				isPrime = NO;
				break;
			}
		}
		if (isPrime) {
			// NSLog (@"%d is prime", i);
			[self appendPrime:i toMutableString: mutableString];
		}
	}
	// with loop done, do one-time set of the view text
	primesView.text = mutableString;
	[mutableString release];
//END:code.PathologicalPrimeCounter.callappendprimetomutablestring

	/* Simple EXC_BAD_ACCESS tutorial - deliberately tries to use a
		bogus reference.  crashes on the nslog() call.
//START:code.PathologicalPrimeCounter.nullreferencestring
	NSString *nullReferenceString;
	NSLog (nullReferenceString);
//END:code.PathologicalPrimeCounter.nullreferencestring
	 */

	/*
	// NSZombieEnabled tutorial - deliberately over-release a string object
	// (stringWithFormat: creates and auto-releasing object, so the manual
	//  release here is inappropriate and sets up an over-release later)
//START:code.PathologicalPrimeCounter.overrelease
	NSString *headerString = [NSString stringWithFormat:
		@"Counted primes to %@", countToField.text];
	NSLog (headerString);
	[headerString release];
//END:code.PathologicalPrimeCounter.overrelease
	 */
}


/*
- (void) appendPrimeToPrimeArea: (int) aPrime {
	NSString *primeString = [[NSString alloc] initWithFormat: @"%d ", aPrime];
	primesView.text = [primesView.text stringByAppendingString: primeString];
}
*/



/* THIS IS A WORKING VERSION OF THIS METHOD.  HOWEVER, IT CALLS THE
   PATHOLOGICAL appendPrimeToPrimeArea:
- (void) countPrimesToSelectedValue {
	int maxPrime = [countToField.text intValue];
	if (maxPrime < 1)
		return;
	// for each int up to maxPrime, check every divisor up to
	// maxPrime/2+1.  there are more efficient prime counters,
	// but this is easy to understand
	for (int i=2; i<maxPrime; i++) {
		int maxDivisor = i/2 + 1;
		BOOL isPrime = YES;
		for (int j=2; j<maxDivisor; j++) {
			if (i%j == 0) {
				// NSLog (@"%d is not prime, divisible by %d", i, j);
				isPrime = NO;
				break;
			}
		}
//START:code.PathologicalPrimeCounter.callappendtoprimearea
		if (isPrime) {
			// NSLog (@"%d is prime", i);
			[self appendPrimeToPrimeArea: i];
		}
//END:code.PathologicalPrimeCounter.callappendtoprimearea
	}
}
 */




/* WARNING: PATHOLOGICAL CODE
   THIS VERSION OF THE METHOD CRASHES BECAUSE OF A DIVIDE BY ZERO ERROR

- (void) countPrimesToSelectedValue {
	int maxPrime = [countToField.text intValue];
	if (maxPrime < 1)
		return;
	// for each int up to maxPrime, check every divisor up to
	// maxPrime/2+1.  there are more efficient prime counters,
	// but this is easy to understand
	for (int i=2; i<maxPrime; i++) {
		int maxDivisor = i/2 + 1;
		BOOL isPrime = YES;
		for (int j=0; j<maxDivisor; j++) {
			if (i%j == 0) {
				NSLog (@"%d is not prime, divisible by %d", i, j);
				isPrime = NO;
				break;
			}
		}
		if (isPrime) {
			NSLog (@"%d is prime", i);
		}
	}
}
 */

/* WARNING: PATHOLOGICAL CODE
 THIS VERSION OF THE METHOD FINDS NO PRIMES BECAUSE ITS INNER LOOP
 ATTEMPTS TO DIVIDE CANDIDATES BY 1, WHICH ALL INTEGERS DIVIDE
 BY EVENLY.
//START:code.PathologicalPrimeCounter.dividesprimesby1
- (void) countPrimesToSelectedValue {
	int maxPrime = [countToField.text intValue];
	if (maxPrime < 1)
		return;
	// for each int up to maxPrime, check every divisor up to
	// maxPrime/2+1.  there are more efficient prime counters,
	// but this is easy to understand
	for (int i=2; i<maxPrime; i++) {
		int maxDivisor = i/2 + 1;
		BOOL isPrime = YES;
		for (int j=1; j<maxDivisor; j++) {
			if (i%j == 0) {
				isPrime = NO;
				break;
			}
		}
		if (isPrime) {
			NSLog (@"%d is prime", i);
		}
	}
}
//END:code.PathologicalPrimeCounter.dividesprimesby1
*/




- (void) handleGoTapped: (id) sender {
	CFAbsoluteTime inTime = CFAbsoluteTimeGetCurrent();
	
	primesView.text = @"";
	[countToField resignFirstResponder]; 	
	[self countPrimesToSelectedValue];

	CFAbsoluteTime outTime = CFAbsoluteTimeGetCurrent();
	CFAbsoluteTime elapsedTime = outTime - inTime;
	NSLog (@"elapsed time: %f", elapsedTime);
	
}

// delegate method to handle user finishing with keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { 
	if (theTextField == countToField) { 
		[countToField resignFirstResponder]; 
		// TODO: count primes
		primesView.text = @"";
		[self countPrimesToSelectedValue];
	} 
	return YES; 
}	


@end
