/*
 
 Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. 

 This file is part of the WOLF3D iOS v2.1 GPL Source Code. 

 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 
 This program 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 General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */

#import "wolf3dAppDelegate.h"
#import "MainMenuViewController.h"
#import "wolf3dViewController.h"
#import "EAGLView.h"
#import <AudioToolbox/AudioServices.h>
#include "../wolfiphone.h"
#include <pthread.h>

//added for downloading SOD content from the internet... added by gsh
extern void Com_Printf(const char* fmt, ... );
//extern void AppendData(NSData* data);
extern void AppendDataToFile(NSData* data);
extern void AppendUserDataToFile(NSData* data);
//extern void SaveData();

//used for downloading custom made map
extern void FinalizeUserDownload(void);

yesNoBoxType_t currentYesNoBox = YESNO_NONE;

#if SPEARSTOREKIT
//was used for storekit
extern void FinalizeDownload();
extern int IsSpearPurchased();
extern int IsSpearInstalled();
extern void BeginStoreKit();
extern void GetSpear();
#endif

extern void DownloadURLConnection(char *url);

extern void iphoneSet2D(void);


//extern bool isAlive;



@interface UIApplication (Private)

- (void)setSystemVolumeHUDEnabled:(BOOL)enabled forAudioCategory:(NSString *)category;
- (void)setSystemVolumeHUDEnabled:(BOOL)enabled;

@end


char iphoneDocDirectory[1024];
char iphoneAppDirectory[1024];

void SysIPhoneVibrate() {
	AudioServicesPlaySystemSound( kSystemSoundID_Vibrate );
}

@implementation wolf3dAppDelegate

@synthesize window;
@synthesize viewController;
@synthesize navigationController;
@synthesize waitingView;
@synthesize player;

- (void)initMenuMusicPlayer {
	NSString *soundFilePath =
				[[NSBundle mainBundle] pathForResource: @"wondering"
												ofType: @"caf"];
	 
	NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
	 
	AVAudioPlayer *newPlayer =
				[[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
													   error: nil];
	[fileURL release];
	
	if ( s_masterVolume != NULL ) {
		newPlayer.volume = s_masterVolume->value * 0.5f;
	} else {
		newPlayer.volume = 0.2f;
	}

	
	newPlayer.numberOfLoops = -1;
	
	self.player = newPlayer;
	[newPlayer release];
	 
	[player prepareToPlay];
}

- (void)startMenuMusic {

	[player play];
}

- (void)stopMenuMusic {

	[player stop];
}



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	// get the documents directory, where we will write configs and save games
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	[documentsDirectory getCString: iphoneDocDirectory 
							maxLength: sizeof( iphoneDocDirectory ) - 1
							encoding: NSASCIIStringEncoding ];
	
	// get the app directory, where our data files live
	paths = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSUserDomainMask, YES);
	NSString *appDirectory = documentsDirectory = [paths objectAtIndex:0];
	[appDirectory getCString: iphoneAppDirectory 
							maxLength: sizeof( iphoneAppDirectory ) - 1
							encoding: NSASCIIStringEncoding ];
	
	// start the flow of accelerometer events
//    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
//    accelerometer.delegate = self;
//    accelerometer.updateInterval = 1.0 / 30.0;
    
#if !TARGET_OS_TV
    [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateDeviceMotion) userInfo:nil repeats:YES];

    self.motionManager = [[CMMotionManager alloc] init];
//    self.motionManager.accelerometerActive = YES;
    self.motionManager.deviceMotionUpdateInterval = 1.0 / 30.0;
    [self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryCorrectedZVertical];
    
    [self.motionManager startAccelerometerUpdates];
#endif
    
	// do all the game startup work
	//iphoneStartup();
	
	
#if SPEARSTOREKIT
	//check if user downloaded spear but didn't purchase
	if (IsSpearInstalled() && !IsSpearPurchased())
	{
		alertPurchaseSpear = [[UIAlertView alloc] initWithTitle:@""//Title" 
												message:@"You have downloaded and installed Spear of Destiny.  Would you like to unlock those levels by purchasing it for $1.99?"
											   delegate:self 
									  cancelButtonTitle:@"No" 
									  otherButtonTitles:@"Yes", nil];	
		
		[alertPurchaseSpear show];
	}
#endif
	
	// Sign up for rotation notifications
#if !TARGET_OS_TV
	[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
	
	[[NSNotificationCenter defaultCenter] addObserver:self 
                selector:@selector(didRotate:) 
                name:UIDeviceOrientationDidChangeNotification
                object:nil];
#endif
	
	// Support rendering at native resolution on devices with Retina displays.
	if ( [[UIScreen mainScreen] respondsToSelector:@selector(scale)] ) {
		deviceScale = UIScreen.mainScreen.scale;
		touchCoordinateScale = UIScreen.mainScreen.scale;
	}
	
	// Screen is initially landscape-left.
	// BEWARE! For UI*Interface*Orientation, Left/Right refers to the location of the home button.
	// BUT, for UI*Device*Orientation, Left/Right refers to the location of the side OPPOSITE the home button!!
#if !TARGET_OS_TV
	[self setScreenForOrientation:UIDeviceOrientationLandscapeRight];
#else
    viddef.width = [UIScreen mainScreen].bounds.size.width * deviceScale;
    viddef.height = [UIScreen mainScreen].bounds.size.height * deviceScale;
    
    float widthRatio = viddef.width / REFERENCE_WIDTH;
    float heightRatio = viddef.height / REFERENCE_HEIGHT;
    
    if ( widthRatio < heightRatio ) {
        screenScale = widthRatio;
    } else {
        screenScale = heightRatio;
    }
#endif
    
    CGRect screenBound = [[UIScreen mainScreen] bounds];
    CGSize screenSize = screenBound.size;
    
    CGFloat screenHeight = screenSize.height;
    CGFloat screenWidth = screenSize.width;
    
    window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
    window.bounds = CGRectMake(0, 0, screenWidth, screenHeight);

	// Create the window programmatically instead of loading from a nib file.
	self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    self.window.backgroundColor = UIColor.blackColor;

	// We will create the OpenGL view here so we can get a context and preload textures, but
	// don't actually add the view to the window until the player enters a level.
	wolf3dViewController *vc = [[wolf3dViewController alloc] initWithNibName:nil bundle:nil];
	self.viewController = vc;
	[self.viewController setActive:NO];
	[vc release];
	
    MainMenuViewController *rootController = [[MainMenuViewController alloc] initWithNibName:[self GetNibNameForDevice: @"MainMenuView"] bundle:nil];
	navigationController = [[UINavigationController alloc] initWithRootViewController:rootController];
	[navigationController setNavigationBarHidden:YES];
	[rootController release];
	
	[window addSubview:navigationController.view];
    [window setRootViewController:self.navigationController];
	[window makeKeyAndVisible];

	return YES;
}

- (void)showOpenGL {
	// Maybe clearing the OpenGL view before displaying will fix the old frame flashing.
	// I don't mind if this blocks until a vsync, becasue it's just a menu.
//    [self.viewController clearAndPresentRenderbuffer];
//
//    [[navigationController view] removeFromSuperview];
//
//    [self.viewController setActive:YES];
//    [window addSubview:[self.viewController view]];
//
//    [self.viewController startAnimation];
    [self.viewController clearAndPresentRenderbuffer];
    [self.viewController setActive:YES];
    [self.navigationController pushViewController:self.viewController animated:NO];
    [self.viewController startAnimation];
    glVisible = YES;
}

- (void)didRotate:(NSNotification *)notification {
#if !TARGET_OS_TV
	UIDeviceOrientation orient = [[UIDevice currentDevice] orientation];
	
	[self setScreenForOrientation:orient];
#endif
}

#if !TARGET_OS_TV
- (void)setScreenForOrientation:(UIDeviceOrientation) orientation {
    
	// Note the the UIDeviceOrientations are REVERSED from the UIInterface orientations!
	switch (orientation) {
		case UIDeviceOrientationLandscapeLeft:
            deviceOrientation = ORIENTATION_LANDSCAPE_RIGHT;
//            viddef.width = [UIScreen mainScreen].bounds.size.height * deviceScale;
//            viddef.height = [UIScreen mainScreen].bounds.size.width * deviceScale;
            viddef.width = [UIScreen mainScreen].bounds.size.width * deviceScale;
            viddef.height = [UIScreen mainScreen].bounds.size.height * deviceScale;
			//[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
			break;
			
		case UIDeviceOrientationLandscapeRight:
			deviceOrientation = ORIENTATION_LANDSCAPE_LEFT;
//            viddef.width = [UIScreen mainScreen].bounds.size.height * deviceScale;
//            viddef.height = [UIScreen mainScreen].bounds.size.width * deviceScale;
            viddef.width = [UIScreen mainScreen].bounds.size.width * deviceScale;
            viddef.height = [UIScreen mainScreen].bounds.size.height * deviceScale;
			//[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
			break;
			
		default:
			break;
	}
	
	float widthRatio = viddef.width / REFERENCE_WIDTH;
	float heightRatio = viddef.height / REFERENCE_HEIGHT;
	
	if ( widthRatio < heightRatio ) {
		screenScale = widthRatio;
	} else {
		screenScale = heightRatio; 
	}
}
#endif

//this is so that we can respond to alertView events (messageboxes)
//but this should only respond to the alertPurchaseSpear
#if !TARGET_OS_TV
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
	if (buttonIndex == 1) {
		switch ( currentYesNoBox ) {
			case YESNO_BUY_PLATINUM: {
				// They clicked yes to buy the platinum edition.
				
				// Set up a fullscreen view with the activity indicator in the middle while
				// we wait for the in-app purchase to complete.
				UIView* topView = [[self.navigationController topViewController] view];
				CGRect waitFrame = topView.frame;
				
				
				[waitingView release];
				waitingView = [[UIView alloc] initWithFrame:waitFrame];
				waitingView.backgroundColor = [UIColor blackColor];
				waitingView.opaque = NO;
				waitingView.alpha = 0.75;
				
				
				UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
				[indicator startAnimating];
				
				[waitingView addSubview:indicator];
				// This mask centers the view in its superview
				indicator.center = indicator.superview.center;
				[indicator release];
				
				[topView addSubview:waitingView];
				
				// Start the request to the app store
				InAppPurchaseSetCallback( inAppPurchaseCallback );
				InAppPurchaseStartPurchase( PLATINUM_UPGRADE_STRING );
				
				break;
			}
				
			case YESNO_GO_TO_WEBSITE:
				//if they clicked yes to going to the idsoftware website
				SysIPhoneOpenURL( "http://www.idsoftware.com/wolfenstein-3d-classic-platinum/" );
				break;
			
			case YESNO_DOWNLOAD_INSTRUCTIONS:
				//this is if they clicked yes to going to the map instructions website
				SysIPhoneOpenURL( "http://www.idsoftware.com/wolfenstein-3d-classic-platinum/mapinstructions/" );
				break;
			
			default:
				break;
		}
	}
	
	/*
	if (alertPurchaseSpear && (alertPurchaseSpear == actionSheet))
	{
		if (buttonIndex != actionSheet.cancelButtonIndex)
			BeginStoreKit();
	}*/
}
#endif

- (void)applicationWillResignActive:(UIApplication *)application {
	[self.viewController stopAnimation]; 
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
	[self.viewController startAnimation];
}

- (void)applicationWillTerminate:(UIApplication *)application {
	[self.viewController stopAnimation];
	
	// Save the game.
	iphoneShutdown();
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
	[self.viewController stopAnimation];
	
	// Save the game.
	iphoneShutdown();
}


- (void)dismissWaitingView {
	if ( waitingView != nil ) {
		[waitingView removeFromSuperview];
		[waitingView release];
		waitingView = nil;
	}
}

#if 1
extern char urlbuffer[1024];
#if !TARGET_OS_TV
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
	// wolf3d:foo should launch wolf3d now... next, add useful URL parameter encoding

	
	if ( SysIPhoneGetContentVersion() == CONTENT_LITE ) {
		iphoneMessageBox("Lite version", "This is a Lite version.  You must purchase Wolfenstein3D to get this feature.");
		return NO;
	}
	
	if (!url)
		return NO;

	NSString *str = [url absoluteString];   //in the future we may wish to parse this string
											//for commands that wolf3d might follow
											//for now we'll just start the storekit
	char buffer[1024];
	
	if(![str getCString:buffer maxLength:1024 encoding:NSUTF8StringEncoding])
	{
		iphoneMessageBox("Not Valid", "There were encoding errors.  Make sure the link is less than 1023 characters in length.");
		return NO;
	}

	//iphoneMessageBox("URL", buffer);
	/*
	if (strcmp(buffer, "wolf3d:foo") == 0)
		GetSpear();	
	*/
	char *pstr = buffer;//&buffer[strlen(buffer) - 5];
	pstr += strlen(buffer) - 4;
	
	if (strcmp(pstr, ".map") != 0)
	{
		iphoneMessageBox("Not Valid", "URL is not a valid map.  Maps must end in \".map\"");
		return NO;
	}
	
	
	if (strncmp(buffer, "wolf3dp:", 8) == 0)
	{
		
		char cURL[1024];
		char *http = "http:";
		strcpy(cURL, http);
		strcpy(cURL + 5, buffer + 8);
		//strcpy(cURL, "http://gregory.hodges.googlepages.com/SODmm.tgz"); //TODO: delete me
		Com_Printf("wolf3dp: installing map %s\n", cURL);
		strcpy(urlbuffer, cURL);
		//download and install this map
		//iphoneMessageBox("wolf3d:", "it's a map TODO install");
		//InstallUserMap();
		DownloadURLConnection(cURL);
	}
	else
	{
		iphoneMessageBox("Not Valid", "URL is not a valid map.  Identifier must start with \"wolf3dp:\"");
		return NO;
	}
	
	return YES;
}
#endif
#endif


- (void)dealloc {
	[viewController release];
	[navigationController release];
	[window release];
	
	[super dealloc];
}

//- (void)restartAccelerometerIfNeeded {
//
//    // I have no idea why this seems to happen sometimes...
//    if ( Sys_Milliseconds() - lastAccelUpdateMsec > 1000 ) {
//        static int count;
//        if ( ++count < 5 ) {
//            printf( "Restarting accelerometer updates.\n" );
//        }
//        UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
//        accelerometer.delegate = self;
//        accelerometer.updateInterval = 1.0 / 30.0;
//    }
//}

//- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
//{
//    float acc[4];
//    acc[0] = acceleration.x;
//    acc[1] = acceleration.y;
//    acc[2] = acceleration.z;
//    acc[3] = acceleration.timestamp;
//    iphoneTiltEvent( acc );
//    lastAccelUpdateMsec = (int)Sys_Milliseconds();
////    Com_Printf("acc: x: %f y: %f z: %f\n", acceleration.x, acceleration.y, acceleration.z);
//
//}

#if !TARGET_OS_TV
-(void)updateDeviceMotion
{
    CMAccelerometerData *deviceMotion = self.motionManager.accelerometerData;

    if(deviceMotion == nil)
    {
        return;
    }

//    CMAcceleration acceleration = deviceMotion.acceleration;
//    Com_Printf("cmm:x: %f y: %f z: %f\n", acceleration.x, acceleration.y, acceleration.z);

    float acc[4];
    acc[0] = deviceMotion.acceleration.x;
    acc[1] = deviceMotion.acceleration.y;
    acc[2] = deviceMotion.acceleration.z;
    acc[3] = deviceMotion.timestamp;
    iphoneTiltEvent( acc );
    lastAccelUpdateMsec = (int)Sys_Milliseconds();
}
#endif

- (NSString*) GetNibNameForDevice:(NSString*) nibName
{
    NSString *extension = @"";
    
#if TARGET_OS_TV
    extension = @"-tvos";
#endif
    
    return [NSString stringWithFormat:@"%@%@", nibName, extension];
}


//------------------------------------------------------------
// connection
// called by the app when data is received during download
// gsh
//-------------------------------------------------------------
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
	// lock the game out temporarily
	pthread_mutex_t eventMutex;
	pthread_mutex_lock( &eventMutex );
/*		
	//display the network activity indicator
	UIApplication* app = [UIApplication sharedApplication]; 
	app.networkActivityIndicatorVisible = YES; // to stop it, set this to NO
	app.statusBarHidden = NO;
*/	
    // append the new data to file
	AppendUserDataToFile(data);
	
	// the game is free to copy the appendedData size now
	pthread_mutex_unlock( &eventMutex );
}

//------------------------------------------------------------------------
// connectionDidFinishLoading
//  this is called when the app finishes downloading
//						the new Spear of Destiny Levels
// gsh
//------------------------------------------------------------------------
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
	Com_Printf("connectionDidFinishLoading called\n");
/*
	//no need to display network traffic anymore
	UIApplication* app = [UIApplication sharedApplication]; 
	app.networkActivityIndicatorVisible = NO; // to stop it, set this to NO
	app.statusBarHidden = YES;
*/	
	//release the connection
	[connection release];
	
	//uncompress/move files/delete unwanted	
	FinalizeUserDownload();
}

//------------------------------------------------------------------------
// connection didFailWithError
// if the connection fails during the download then this is called
// gsh
//------------------------------------------------------------------------
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
	//let user know that the connection failed
	iphoneMessageBox("Connection Failed", "Please check your connection and try again later.");
	
	//return the user to the main menu
	menuState = IPM_MAIN;
/*	
	//no need to display network traffic anymore
	UIApplication* app = [UIApplication sharedApplication]; 
	app.networkActivityIndicatorVisible = NO; // to stop it, set this to NO
	app.statusBarHidden = YES;	*/
}
/*
- (void)setDownloadResponse:(NSURLResponse *)aDownloadResponse
{
    [aDownloadResponse retain];
    [downloadResponse release];
    downloadResponse = aDownloadResponse;
}

- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response
{
    // reset the progress, this might be called multiple times
    bytesReceived=0;
	
    // retain the response to use later
    [self setDownloadResponse:response];
}

- (void)download:(NSURLDownload *)download didReceiveDataOfLength:(unsigned)length
{
    long long expectedLength=[[self downloadResponse] expectedContentLength];
	
    bytesReceived=bytesReceived+length;
	
    if (expectedLength != NSURLResponseUnknownLength) {
        // if the expected content length is
        // available, display percent complete
        float percentComplete=(bytesReceived/(float)expectedLength)*100.0;
        NSLog(@"Percent complete - %f",percentComplete);
    } else {
        // if the expected content length is
        // unknown just log the progress
        NSLog(@"Bytes received - %d",bytesReceived);
    }
}
*/

- (void)GLtoMainMenu {
	[self.navigationController popToRootViewControllerAnimated:NO];
	[viewController setActive:NO];
	[[viewController view] removeFromSuperview];
	[window addSubview:navigationController.view];
    glVisible = NO;
}

- (void)GLtoPreviousMenu {
	[viewController setActive:NO];
	[[viewController view] removeFromSuperview];
	[window addSubview:navigationController.view];
    glVisible = NO;
}

- (BOOL) isGLVisible {
    return glVisible;
}
@end

void iphoneStartMainMenu() {
	Sound_StopBGTrack();
	iphoneStartMenuMusic();
	numTouches = 0;
	numPrevTouches = 0;
	wolf3dAppDelegate *app = (wolf3dAppDelegate*)[[UIApplication sharedApplication] delegate];
	[app GLtoMainMenu];
}

void iphoneStartPreviousMenu() {
	wolf3dAppDelegate *app = (wolf3dAppDelegate*)[[UIApplication sharedApplication] delegate];
	[app GLtoPreviousMenu ];
}

void inAppPurchaseCallback( InAppPurchaseResult result ) {
	wolf3dAppDelegate* app = (wolf3dAppDelegate*)[[UIApplication sharedApplication] delegate];
	[app dismissWaitingView];
}

