//
//  GMSAppDelegate.m
//  GMS Sample
//
/*
 Version: 1.0
 
 Disclaimer: IMPORTANT:  This software is supplied to you by Genesys
 Telecommunications Laboratories Inc ("Genesys") in consideration of your agreement
 to the following terms, and your use, installation, modification or redistribution
 of this Genesys software constitutes acceptance of these terms.  If you do not
 agree with these terms, please do not use, install, modify or redistribute this
 Genesys software.
 
 In consideration of your agreement to abide by the following terms, and subject
 to these terms, Genesys grants you a personal, non-exclusive license, under
 Genesys's copyrights in this original Genesys software (the "Genesys Software"), to
 use, reproduce, modify and redistribute the Genesys Software, with or without
 modifications, in source and/or binary forms; provided that if you redistribute
 the Genesys Software in its entirety and without modifications, you must retain
 this notice and the following text and disclaimers in all such redistributions
 of the Genesys Software.
 
 Neither the name, trademarks, service marks or logos of Genesys Inc. may be used
 to endorse or promote products derived from the Genesys Software without specific
 prior written permission from Genesys.  Except as expressly stated in this notice,
 no other rights or licenses, express or implied, are granted by Genesys herein,
 including but not limited to any patent rights that may be infringed by your
 derivative works or by other works in which the Genesys Software may be
 incorporated.
 
 The Genesys Software is provided by Genesys on an "AS IS" basis.  GENESYS MAKES NO
 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 PURPOSE, REGARDING THE GENESYS SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
 COMBINATION WITH YOUR PRODUCTS.
 
 IN NO EVENT SHALL GENESYS BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
 DISTRIBUTION OF THE GENESYS SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
 CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 GENESYS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 Copyright (C) 2013 Genesys Inc. All Rights Reserved.
 */

#import "GMSAppDelegate.h"
#import "GMSRequestViewController.h"
#import "UIAlertViewBlock.h"
#import "GMSUtil.h"
#import "GMSChatViewController.h"

#define kGMSUserID          @"GMSUserID"
#define kGMSUserPwd         @"GMSUserPwd"
#define kGMSWay2Connect     @"GMSWay2Connect"
#define kGMSProblemInfo     @"GMSProblemInfo"
#define kGMSProblemContent  @"GMSProblemContent"
#define kGMSAppPath         @"GMSAppPath"
#define kGMSServerURL       @"GMSServerURL"
#define kGMSServerURLs      @"GMSServerURLs"
#define kGMSCallbackServiceName @"GMSCallbackServiceName"
#define kGMSServerAPNDebug  @"GMSServerAPNDebug"
#define kGMSSegment         @"GMSSegment"
#define kGMSTheme           @"GMSTheme"
#define kGMSPhone           @"GMSPhone"
#define kGMSLoginRequired   @"GMSLoginRequired"
#define kGMSAudioEnabled    @"GMSAudioEnabled"
#define kGMSProvideCode     @"GMSProvideCode"
#define kGMSClearChatOnNewSession @"GMSClearChatOnNewSession"
#define kGMSScreenSharingServiceName @"GMSScreenSharingServiceName"

extern NSString* CTSettingCopyMyPhoneNumber();

@interface GMSAppDelegate ()
{
    BOOL _locationManagerStarted;
}
@end

@implementation GMSAppDelegate

- (void) setServerURLSelected:(int)serverURLSelected
{
    _serverURLSelected = serverURLSelected;
    if (serverURLSelected < [_serverURLs count]) { // Might not be true when loading defaults at startup the first time
        [GMSUtil setBaseURL:[_serverURLs objectAtIndex:serverURLSelected]];
    }
}

#pragma APN Processing

- (void) processAPN:(NSDictionary *)userInfo
{
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
    
    GMSRequestViewController *gmsR;
    
    //Update Log View
    [[NSNotificationCenter defaultCenter] postNotificationName:kUpdateNotification
                                                        object:self
                                                      userInfo:@{@"direction":@(fromGMS), @"text":[NSString stringWithFormat:@"didReceiveRemoteNotification: %@", userInfo]}];

    //Find GMSRequestViewController
    UITabBarController *tb = (UITabBarController *)self.window.rootViewController;
    for (id tbc in tb.viewControllers) {
        if ([tbc isKindOfClass:[UINavigationController class]] && [[tbc viewControllers][0] isKindOfClass:[GMSRequestViewController class]]) {
            gmsR = [tbc viewControllers][0];
            break;
        }
    }    
    
    if (userInfo[@"message"]) {
        
        // Dending on how the notification was encoded, the message object may be a string
        // containing JSON that needs to be parsed or a dictionary object.
        NSDictionary *messageDict = nil;
        if ([userInfo[@"message"] isKindOfClass:[NSString class]]) {
            NSError *jsonParsingError = nil;
            messageDict = [NSJSONSerialization JSONObjectWithData:[userInfo[@"message"] dataUsingEncoding:NSUTF8StringEncoding]
                                                           options:0
                                                             error:&jsonParsingError];
        }
        else if ([userInfo[@"message"] isKindOfClass:[NSDictionary class]]) {
            messageDict = userInfo[@"message"];
        }
        
        // If the messageDict contains the "_action" key assumed it's a callback notification where "_action" specifies a URL to call
        if (messageDict != nil) {
            NSString *action = messageDict[@"_action"];
            if (action != nil) {
                
                NSString *serviceId = messageDict[@"_id"];
                NSString *dialogPath = [[@"/1/service" stringByAppendingPathComponent:serviceId] stringByAppendingPathComponent:action];
                
                if (dialogPath) {
                    [gmsR.dMenu submitRequestWithPath:dialogPath method:@"POST" params:nil headers:nil completionBlock:nil];
                }
            }
        }
    }
}

- (void) loadDefaults
{
    _userID =  [[NSUserDefaults standardUserDefaults] stringForKey:kGMSUserID];
    _userPwd = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSUserPwd];
    _way2Connect = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSWay2Connect];
    _problemInfoLevel = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSProblemInfo];
    _problemContent = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSProblemContent];
    _appPath = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSAppPath];    
    _serverURLs = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:kGMSServerURLs]];
    self.serverURLSelected = [[NSUserDefaults standardUserDefaults] integerForKey:kGMSServerURL];
    _callbackServiceName = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSCallbackServiceName];
    _serverAPNDebug = [[NSUserDefaults standardUserDefaults] boolForKey:kGMSServerAPNDebug];
    _customerSegment = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSSegment];
    _themeFlavor = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSTheme];
    _loginRequired = [[NSUserDefaults standardUserDefaults] boolForKey:kGMSLoginRequired];
    _audioEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kGMSAudioEnabled];
    _provideCode = [[NSUserDefaults standardUserDefaults] boolForKey:kGMSProvideCode];
    _clearChatOnNewSession = [[NSUserDefaults standardUserDefaults] boolForKey:kGMSClearChatOnNewSession];
    _screenSharingServiceName = [[NSUserDefaults standardUserDefaults] stringForKey:kGMSScreenSharingServiceName];
    
//    _audioRecordEnabled = YES;
    
    //Note: retrieving your own private number requires use of Apple private APIs
    _contactNumber = CTSettingCopyMyPhoneNumber();
    
    if (_userID == nil) {
        //Not initialized - read defaults from Defaults.plist file
#ifdef DEBUG
        NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Defaults-Debug" ofType:@"plist"];
#else
        NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Defaults" ofType:@"plist"];
#endif
        NSDictionary *plistD = [NSDictionary dictionaryWithContentsOfFile:plistPath];
        
        _userID = plistD[kGMSUserID];
        _userPwd = plistD[kGMSUserPwd];
        _way2Connect = plistD[kGMSWay2Connect];
        _problemInfoLevel = plistD[kGMSProblemInfo];
        _problemContent = plistD[kGMSProblemContent];
        _appPath = plistD[kGMSAppPath];
        _serverURLs = [NSMutableArray arrayWithArray:plistD[kGMSServerURLs]];
        self.serverURLSelected = 0;
        _callbackServiceName = plistD[kGMSCallbackServiceName];
        _serverAPNDebug = [[plistD objectForKey:kGMSServerAPNDebug] boolValue];
        _customerSegment = plistD[kGMSSegment];
        _themeFlavor = plistD[kGMSTheme];
        _loginRequired = [[plistD objectForKey:kGMSLoginRequired] boolValue];
        _audioEnabled = [[plistD objectForKey:kGMSAudioEnabled] boolValue];
        _provideCode = [[plistD objectForKey:kGMSProvideCode] boolValue];
        _clearChatOnNewSession = [[plistD objectForKey:kGMSClearChatOnNewSession] boolValue];
        _screenSharingServiceName = plistD[kGMSScreenSharingServiceName];
        if ([_contactNumber length] == 0) {
            _contactNumber = plistD[kGMSPhone];
        }
        
        // Defaults never have been set. Initialize user defaults.
		NSDictionary *appDefaults = @{kGMSUserID : _userID, \
                                kGMSUserPwd : _userPwd, \
                                kGMSProblemInfo : _problemInfoLevel, \
                                kGMSWay2Connect : _way2Connect, \
                                kGMSProblemContent : _problemContent, \
                                kGMSAppPath : _appPath, \
                                kGMSServerURL : @(_serverURLSelected), \
                                kGMSServerURLs : _serverURLs, \
                                kGMSCallbackServiceName : _callbackServiceName, \
                                kGMSServerAPNDebug : @(_serverAPNDebug), \
                                kGMSSegment : _customerSegment, \
                                kGMSTheme : _themeFlavor, \
                                kGMSLoginRequired : @(_loginRequired), \
                                kGMSAudioEnabled : @(_audioEnabled), \
                                kGMSProvideCode : @(_provideCode), \
                                kGMSClearChatOnNewSession : @(_clearChatOnNewSession), \
                                kGMSScreenSharingServiceName : _screenSharingServiceName, \
                                kGMSPhone : _contactNumber};
		[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
		[[NSUserDefaults standardUserDefaults] synchronize];
    }
}

- (void) saveDefaults {
	// Update user defaults
	[[NSUserDefaults standardUserDefaults] setObject:_userID forKey:kGMSUserID];
	[[NSUserDefaults standardUserDefaults] setObject:_userPwd forKey:kGMSUserPwd];
	[[NSUserDefaults standardUserDefaults] setObject:_way2Connect forKey:kGMSWay2Connect];
	[[NSUserDefaults standardUserDefaults] setObject:_problemInfoLevel forKey:kGMSProblemInfo];
	[[NSUserDefaults standardUserDefaults] setObject:_problemContent forKey:kGMSProblemContent];
	[[NSUserDefaults standardUserDefaults] setObject:_appPath forKey:kGMSAppPath];
	[[NSUserDefaults standardUserDefaults] setInteger: _serverURLSelected forKey:kGMSServerURL];
	[[NSUserDefaults standardUserDefaults] setObject:_serverURLs forKey:kGMSServerURLs];
	[[NSUserDefaults standardUserDefaults] setObject:_callbackServiceName forKey:kGMSCallbackServiceName];
	[[NSUserDefaults standardUserDefaults] setBool:_serverAPNDebug forKey:kGMSServerAPNDebug];
	[[NSUserDefaults standardUserDefaults] setObject:_customerSegment forKey:kGMSSegment];
	[[NSUserDefaults standardUserDefaults] setObject:_themeFlavor forKey:kGMSTheme];
	[[NSUserDefaults standardUserDefaults] setBool:_loginRequired forKey:kGMSLoginRequired];
	[[NSUserDefaults standardUserDefaults] setBool:_audioEnabled forKey:kGMSAudioEnabled];
	[[NSUserDefaults standardUserDefaults] setBool:_provideCode forKey:kGMSProvideCode];
    [[NSUserDefaults standardUserDefaults] setBool:_clearChatOnNewSession forKey:kGMSClearChatOnNewSession];
	[[NSUserDefaults standardUserDefaults] setObject:_contactNumber forKey:kGMSPhone];
	[[NSUserDefaults standardUserDefaults] synchronize];
    [[NSUserDefaults standardUserDefaults] setObject:_screenSharingServiceName forKey:kGMSScreenSharingServiceName];
}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [GMSUtil initialize];
    
    // Override point for customization after application launch.
    
    NSLog(@"Registering for push notifications...");
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
    }

    [self loadDefaults];
    
    _locationManager = [[CLLocationManager alloc] init];
    [_locationManager setDelegate:self];
    CLAuthorizationStatus as = [CLLocationManager authorizationStatus];
    _locationManagerStarted = NO;
    if (as == kCLAuthorizationStatusNotDetermined) {
        [_locationManager requestWhenInUseAuthorization]; // Result will be returned async to didChangeAuthorizationStatus
    }
    else if (as != kCLAuthorizationStatusDenied) {
        [self startLocationManager];
    }
    
    //Get current date
    _date = [NSDate date];
    
    if (launchOptions[@"UIApplicationLaunchOptionsRemoteNotificationKey"]) {
        //App was lunched with Push Notification
        [self processAPN:launchOptions[@"UIApplicationLaunchOptionsRemoteNotificationKey"]];
    }
    
    return YES;
}

- (void)startLocationManager
{
    if (_locationManagerStarted)
        return;
    
    _locationManagerStarted = YES;
    [_locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
    [_locationManager startUpdatingLocation];
    _location = [_locationManager location].coordinate;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    [self saveDefaults];
    
    // Let the chatview controller close the cometd connection
    if (_chatViewController != nil) {
        [_chatViewController applicationDidEnterBackground];
    }
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    
    // Let the chatview controller restart the cometd connection
    if (_chatViewController != nil) {
        [_chatViewController applicationDidBecomeActive];
    }
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    [self saveDefaults];
    
    [_locationManager stopUpdatingLocation];
    [_locationManager setDelegate:nil];
    _locationManager = nil;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    
    NSString *str  = [NSString stringWithFormat:@"%@", deviceToken];
    
    _notifyToken = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
    _notifyToken = [_notifyToken stringByReplacingOccurrencesOfString:@"<" withString:@""];
    _notifyToken = [_notifyToken stringByReplacingOccurrencesOfString:@">" withString:@""];
    
    NSLog(@"Notification token: %@", _notifyToken);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
    _notifyToken = @"Error";
    NSLog(@"Error registering for APN: %@", err);
    
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    
    // get state
    UIApplicationState state = [application applicationState];
    if (state == UIApplicationStateActive) {
        //the app is in the foreground
        NSString *message = nil;
        if (userInfo[@"aps"] && userInfo[@"aps"][@"alert"]) {
            id alert = userInfo[@"aps"][@"alert"];
            if ([alert isKindOfClass:[NSDictionary class]]) {
                message = alert[@"body"];
            }
            else if ([alert isKindOfClass:[NSString class]]) {
                message = (NSString*) alert;
            }
        }
        
        if (message == nil)
            return; // Should not normally occur
        
        UIAlertViewBlock *block = [[UIAlertViewBlock alloc] initWithTitle:@"Message from GMS"
                                                                  message:message
                                                               completion:^(BOOL okPressed, NSInteger buttonIndex, NSDictionary *txtFieldParams) {
                                                                   if (okPressed) {
                                                                       [self processAPN:userInfo];
                                                                   }
                                                               }
                                                        cancelButtonTitle:@"Proceed"
                                                        otherButtonTitles:@"Cancel", nil];
        [block show];
    }
    else {
        //Application was brought from background to foreground
        [self processAPN:userInfo];
    }
}

#pragma Location Manager delegates

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    if (status != kCLAuthorizationStatusDenied) {
        [self startLocationManager];
    }
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    _location = newLocation.coordinate;
}

//iOS 6

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations objectAtIndex:0];
    _location = location.coordinate;
}

@end
