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


#import "CreateFileViewController.h"


@implementation CreateFileViewController

@synthesize parentDirectoryPath, directoryViewController;
@synthesize fileNameField, fileContentsView;


/* alternative method bodies for createNewFile:
 
 // an easy, in-memory way
 NSData *newFileContents = [fileContentsView.text dataUsingEncoding: NSUTF8StringEncoding];
 [[NSFileManager defaultManager] createFileAtPath:newFilePath contents:newFileContents attributes:nil];
 NSLog (@"wrote to file");

 // another easy way
 [[NSFileManager defaultManager] createFileAtPath:newFilePath contents:nil attributes:nil];
 [fileContentsView.text writeToFile:newFilePath
	atomically:NO encoding:NSASCIIStringEncoding error:nil];
 NSLog (@"wrote to file");
*/

// this is the blocking way to write the file with an NSOutputStream
//START:code.FilesystemExplorer.write-file-stream
- (void)  createNewFile {
	NSString *newFilePath =	[parentDirectoryPath
				stringByAppendingPathComponent: fileNameField.text];
	
	[[NSFileManager defaultManager] createFileAtPath:newFilePath
		contents:nil attributes:nil];
	NSOutputStream *outputStream =
	[NSOutputStream outputStreamToFileAtPath: newFilePath
		append:NO];
	[outputStream open];
	const char* cString = [fileContentsView.text UTF8String];
	UInt16 stringOffset = 0;
	uint8_t outputBuf [1];
	while ( ((outputBuf[0] = cString[stringOffset]) != 0) &&
		   [outputStream hasSpaceAvailable] ) {
		[outputStream write: (const uint8_t *) outputBuf maxLength: 1];
		stringOffset++;
	}
	[outputStream close];
	
	// force update of previous page
	[directoryViewController loadDirectoryContents];
	[directoryViewController.tableView reloadData];
	
	// dismiss this view
	[self.navigationController popViewControllerAnimated:YES];
	
}
//END:code.FilesystemExplorer.write-file-stream


//START:code.FilesystemExplorer.setupasyncfilesave
- (void) setUpAsynchronousContentSave {
	[asyncOutputStream release];
	[outputData release];
	outputData = [[fileContentsView.text  // <label id="code.FilesystemExplorer.setupasyncfilesave.data"/>
		dataUsingEncoding: NSUTF8StringEncoding] retain];
	outputRange.location = 0; // <label id="code.FilesystemExplorer.setupasyncfilesave.setuprange"/>
	NSString *newFilePath =	[parentDirectoryPath
			stringByAppendingPathComponent: fileNameField.text];
	[[NSFileManager defaultManager] createFileAtPath:newFilePath
			contents:nil attributes:nil];
	asyncOutputStream =	[[NSOutputStream alloc] // <label id="code.FilesystemExplorer.setupasyncfilesave.allocstream"/>
				initToFileAtPath: newFilePath append: NO];
	[asyncOutputStream setDelegate: self]; // <label id="code.FilesystemExplorer.setupasyncfilesave.setdelegate"/>
	[asyncOutputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] // <label id="code.FilesystemExplorer.setupasyncfilesave.schedulestream"/>
					forMode:NSDefaultRunLoopMode];
	[asyncOutputStream open]; // <label id="code.FilesystemExplorer.setupasyncfilesave.openstream"/>
}	
//END:code.FilesystemExplorer.setupasyncfilesave

//START:code.FilesystemExplorer.async-file-save-delegate
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
	NSOutputStream *outputStream = (NSOutputStream*) theStream;
	BOOL shouldClose = NO;
	switch (streamEvent) {
		case NSStreamEventHasSpaceAvailable: {
			uint8_t outputBuf [1]; // <label id="code.FilesystemExplorer.async-file-save-delegate.buffer"/>
			outputRange.length = 1;
			[outputData getBytes:&outputBuf range:outputRange];  // <label id="code.FilesystemExplorer.async-file-save-delegate.copybytestobuffer"/>
			[outputStream write: outputBuf maxLength: 1];  // <label id="code.FilesystemExplorer.async-file-save-delegate.writebytestostream"/>
			if (++outputRange.location == [outputData length]) {  // <label id="code.FilesystemExplorer.async-file-save-delegate.checkendofdata"/>
				shouldClose = YES;
			}
			break;
		}
		case NSStreamEventErrorOccurred: {
			// dialog the error
			NSError *error = [theStream streamError];
			if (error != NULL) {
				UIAlertView *errorAlert = [[UIAlertView alloc]
				   initWithTitle: [error localizedDescription]
				   message: [error localizedFailureReason]
				   delegate:nil
				   cancelButtonTitle:@"OK"
				   otherButtonTitles:nil];
				[errorAlert show];
				[errorAlert release];
			}
			shouldClose = YES;
			break;
		}
		case NSStreamEventEndEncountered:
			shouldClose = YES;
	}
	if (shouldClose) {
		[outputStream removeFromRunLoop: [NSRunLoop currentRunLoop]  // <label id="code.FilesystemExplorer.async-file-save-delegate.removefromrunloop"/>
			forMode:NSDefaultRunLoopMode];
		[theStream close]; // <label id="code.FilesystemExplorer.async-file-save-delegate.closestream"/>
		
		// force update of previous page and dismiss view
		[directoryViewController loadDirectoryContents];  // <label id="code.FilesystemExplorer.async-file-save-delegate.updatepreviousview.start"/>
		[directoryViewController.tableView reloadData];
		[self.navigationController popViewControllerAnimated:YES]; // <label id="code.FilesystemExplorer.async-file-save-delegate.updatepreviousview.end"/>
	}
}
//END:code.FilesystemExplorer.async-file-save-delegate



- (BOOL)textFieldShouldReturn:(UITextField *)textField {
	[fileNameField resignFirstResponder];
	return YES;
}



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

// Implement viewDidLoad to do additional setup after loading the view.
//START:code.FilesystemExplorer.createfileviewdidload
- (void)viewDidLoad {
    [super viewDidLoad];
	UIBarButtonItem *saveButton =
		[[UIBarButtonItem alloc]
			initWithBarButtonSystemItem: UIBarButtonSystemItemSave
			target: self
			action: @selector(setUpAsynchronousContentSave)];
	 self.navigationItem.rightBarButtonItem = saveButton;
}
//END:code.FilesystemExplorer.createfileviewdidload

- (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 {
	[parentDirectoryPath release];
	[directoryViewController release];
	[asyncOutputStream release];
	[fileNameField release];
	[fileContentsView release];
	[outputData release];
    [super dealloc];
}


@end
