//
//  FTAsyncRequest.m
//  FelineTek iPhone ToolBox. Copyright (C) 2009 FelineTek.
//
//  FelineTek iPhone ToolBox is free software; you can redistribute it 
//  and/or modify it under the terms of the GNU Lesser General Public
//  License (LGPL) as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  For more info see http://www.felinetek.com/FTToolbox
//
//  Created by Panos Hadjikomninos on 13/03/2009.
//  Copyright (C) 2009 FelineTek. All rights reserved.
//

#import "FTAsyncRequest.h"


@implementation FTAsyncRequest




@synthesize timeout, encoding, contentType;




#pragma mark -
#pragma mark Initialization


- (id)initWithUrl:(NSString *)urlp delegate:(id) obj onSuccess:(SEL) ssuccess onFailure:(SEL) sfailure
{	
	
	url= [[NSString alloc] initWithString:urlp];
	
	
	delegate=obj;
	[delegate retain];
	
	successSelector=ssuccess;
	errorSelector=sfailure;
	
	timeout=24;
	encoding=NSUTF8StringEncoding;
	
	self.contentType=@"text/plain; charset=utf-8";
	
    return [super init];
}




- (void)dealloc
{	
	
	[url release];
	
	if (connection != nil) 
	{
		[connection cancel];
		[connection release];
	}
	
	if (receivedData != nil) [receivedData release];
	
	[delegate release];
	[contentType release];
	
    [super dealloc];
}



- (NSData *) getData
{
	return receivedData;
}





#pragma mark -
#pragma mark Implied Thread Firing


- (void)getAsynchronously
{ 
	
	if (receivedData != nil) [receivedData release];
	receivedData=[[NSMutableData alloc] initWithCapacity:1000];	
	
	[receivedData setLength:0];
	
	
	NSURL  *nsurl = [NSURL URLWithString:url];
	NSMutableURLRequest *request = [NSURLRequest requestWithURL:nsurl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:timeout];
	
	[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
	
	
	connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
	
	if (!connection) {
		FT_LOGS(FT_ERROR,@"Failed Memory Allocation For NSURLConnection");
		
		NSNumber *number = [[NSNumber alloc] initWithInt:FT_NO_CONNECTION];
		
		[delegate performSelector:errorSelector withObject:number];
		
		[number release];
		
		return;
	} 
	
	
	// Otherwise Connection Failure or Success invoke callbacks
	// --------------------------------------------------------
	
} 




- (void)postAsynchronously: (NSData *) body
{ 
		
	
	if (receivedData != nil) [receivedData release];
	receivedData=[[NSMutableData alloc] initWithCapacity:1000];	
	
	[receivedData setLength:0];
	
	
	
	NSURL  *nsurl = [NSURL URLWithString:url];
	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nsurl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:timeout];
	
	
	[request setHTTPMethod: @"POST" ];
	[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
	[request setHTTPBody:body];
	

	
	connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
	
	if (!connection) {
		FT_LOGS(FT_ERROR,@"Failed Memory Allocation For NSURLConnection");
		
		NSNumber *number = [[NSNumber alloc] initWithInt:FT_NO_CONNECTION];
		
		[delegate performSelector:errorSelector withObject:number];
		
		[number release];
		
		return;
	} 
	
	
	// Otherwise Connection Failure or Success invoke callbacks
	// --------------------------------------------------------
	
} 





- (id) FTinitWithUrl:(NSString *)turl delegate:(id) obj onSuccess:(SEL) ssuccess onFailure:(SEL) sfailure
{
	return [self initWithUrl:turl delegate:obj onSuccess:ssuccess onFailure:sfailure];
}





- (void) FTgetAsynchronously
{
	[self getAsynchronously];
}






- (void) FTpostAsynchronously: (NSData *) body
{
	[self postAsynchronously:body];
}





- (NSData *) FTgetData
{
	return [self getData];
}




#pragma mark -
#pragma mark NSURLConnection Delegate


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    // This method may be called multiple times (as in redirect), so each time we reset the data
	// -----------------------------------------------------------------------------------------
    [receivedData setLength:0]; 
	
} 




- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [receivedData appendData:data]; 
} 




- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error 
{ 
	
	
    FT_LOGD(FT_WARNING,@"NSURLConnection failed! Error - %@ %d", [error localizedDescription], [error code]); 
	
	NSNumber *number = [[NSNumber alloc] initWithInt:error.code];
	
	[delegate performSelector:errorSelector withObject:number];
	
	[number release];
	
	// There is no other one. This is it baby!
	[connection release]; 
	connection=nil;
	
} 




- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection 
{ 
	
	
    FT_LOGU(FT_DEBUGGING,@"NSURLConnection Succeeded! Received %d bytes of data",[receivedData length]); 
	
	NSMutableString *str = [[NSMutableString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];	
	
	FT_LOGS(FT_VERBOSE,str);
	[str release];
	
	
	NSData *data = [[NSData alloc] initWithData: receivedData];
	
	
	[delegate performSelector:successSelector withObject:data];
	
	[data release];	
	
	// There is no other one. This is it baby!
	[connection release]; 
	connection=nil;
	
	// $$$$ >>>> CRASH: [receivedData release];
	
}


@end
