/*
 
 Phonegap DatePicker Plugin for using Cordova 3 and iOS 7
 https://github.com/sectore/phonegap3-ios-datepicker-plugin
 
 Based on a previous plugin version by Greg Allen and Sam de Freyssinet.
 
 Rewrite by Jens Krause (www.websector.de)
 
 MIT Licensed
 
 */

#import "DatePicker.h"
#import <Cordova/CDV.h>

@interface DatePicker ()

@property (nonatomic) IBOutlet UIView* datePickerContainer;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *datePickerComponentsContainerVSpace;
@property (nonatomic) IBOutlet UIView* datePickerComponentsContainer;
@property (nonatomic) IBOutlet UIButton *cancelButton;
@property (nonatomic) IBOutlet UIButton *doneButton;
@property (nonatomic) IBOutlet UIDatePicker *datePicker;

@end

@implementation DatePicker

#define ANIMATION_DURATION 0.3

#pragma mark - UIDatePicker

- (void)show:(CDVInvokedUrlCommand*)command {
  NSMutableDictionary *options = [command argumentAtIndex:0];
  [self showForPhone: options];
}

- (BOOL)showForPhone:(NSMutableDictionary *)options {
  if(!self.datePickerContainer){
    [[NSBundle mainBundle] loadNibNamed:@"DatePicker" owner:self options:nil];
  } else {
      self.datePickerContainer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
  }
  
  [self updateDatePicker:options];
  [self updateCancelButton:options];
  [self updateDoneButton:options];
  if (@available(iOS 13.0, *)) {
    self.datePickerContainer.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
  }
  
  [self.datePicker addTarget:self action:@selector(datePickerScrollerChanged:) forControlEvents:UIControlEventValueChanged];

  UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
  
  CGFloat width;
  CGFloat height;
  
  [self.datePickerContainer removeFromSuperview];
  
  if(UIInterfaceOrientationIsLandscape(deviceOrientation)){
    width = self.webView.superview.frame.size.width;
    height= self.webView.superview.frame.size.height;
  } else {
    width = self.webView.superview.frame.size.width;
    height= self.webView.superview.frame.size.height;
  }
  
  self.datePickerContainer.frame = CGRectMake(0, 0, width, height);
  
  [self.webView.superview addSubview: self.datePickerContainer];
  [self.datePickerContainer layoutIfNeeded];

  CGRect frame = self.datePickerComponentsContainer.frame;
  self.datePickerComponentsContainer.frame = CGRectOffset(frame,
                                                          0,
                                                          frame.size.height );
  
  
  self.datePickerContainer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
  
  [UIView animateWithDuration:ANIMATION_DURATION
                        delay:0
                      options:UIViewAnimationOptionCurveEaseOut
                   animations:^{
    self.datePickerComponentsContainer.frame = frame;
    self.datePickerContainer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];

  } completion:^(BOOL finished) {
    
  }];
  
  return true;
}

- (void)hide {
  
    CGRect frame = CGRectOffset(self.datePickerComponentsContainer.frame,
                                0,
                                self.datePickerComponentsContainer.frame.size.height);
    
    [UIView animateWithDuration:ANIMATION_DURATION
                          delay:0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                       self.datePickerComponentsContainer.frame = frame;
                       self.datePickerContainer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
                       
                     } completion:^(BOOL finished) {
                       [self.datePickerContainer removeFromSuperview];
                     }];
}

#pragma mark - Actions
- (IBAction)doneAction:(id)sender {
  [self jsDateSelected];
  [self hide];
}
  
- (IBAction)cancelAction:(id)sender {
  [self jsCancel];
  [self hide];
}


- (void)dateChangedAction:(id)sender {
  [self jsDateSelected];
}

- (void)datePickerScrollerChanged:(id)sender {
  UIDatePicker *datePicker = sender;
  if(self.datePicker == datePicker){
    printf("Value of picker is %s\n", 
      [[[self.datePicker date] description] cString]);

      NSTimeInterval seconds = [self.datePicker.date timeIntervalSince1970];
      NSString *jsCallback = [NSString stringWithFormat:@"datePicker._datePickerChanged(\"%f\");", seconds];

      [self.commandDelegate evalJs:jsCallback];

  }
}


#pragma mark - JS API

- (void)jsCancel {
  NSLog(@"JS Cancel is going to be executed");
  NSString *jsCallback = @"datePicker._dateSelectionCanceled();";
    
  [self.commandDelegate evalJs:jsCallback];
}

- (void)jsDateSelected {
  NSTimeInterval seconds = [self.datePicker.date timeIntervalSince1970];
  NSString *jsCallback = [NSString stringWithFormat:@"datePicker._dateSelected(\"%f\");", seconds];
  [self.commandDelegate evalJs:jsCallback];
}

#define DATETIME_FORMAT @"yyyy-MM-dd'T'HH:mm:ss'Z'"

- (void)updateDatePicker:(NSMutableDictionary *)options {
  NSDateFormatter *formatter = [self createISODateFormatter: DATETIME_FORMAT timezone:[NSTimeZone defaultTimeZone]];
  NSString *mode = [options objectForKey:@"mode"];
  NSString *dateString = [options objectForKey:@"date"];
  BOOL allowOldDates = ([[options objectForKey:@"allowOldDates"] intValue] == 0) ? NO : YES;
  BOOL allowFutureDates = ([[options objectForKey:@"allowFutureDates"] intValue] == 0) ? NO : YES;
  NSString *minDateString = [options objectForKey:@"minDate"];
  NSString *maxDateString = [options objectForKey:@"maxDate"];
  NSString *minuteIntervalString = [options objectForKey:@"minuteInterval"];
  NSInteger minuteInterval = [minuteIntervalString integerValue];
  NSString *countDownDurationString = [options objectForKey:@"countDownDuration"];
  NSInteger countDownDuration = [countDownDurationString integerValue];
  NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:[options objectForKey:@"locale"]];

  
  if (allowOldDates) {
    self.datePicker.minimumDate = nil;
  }
  else {
    self.datePicker.minimumDate = [NSDate date];
  }
  
  if(minDateString && minDateString.length > 0){
    self.datePicker.minimumDate = [formatter dateFromString:minDateString];
  }
  
  if (allowFutureDates) {
    self.datePicker.maximumDate = nil;
  }
  else {
    self.datePicker.maximumDate = [NSDate date];
  }
  
  if(maxDateString && maxDateString.length > 0){
    self.datePicker.maximumDate = [formatter dateFromString:maxDateString];
  }
  
   @try{
    self.datePicker.date = [formatter dateFromString:dateString];
  } @catch (NSException *exception) {
    NSLog(@"Write failed with error: %@", exception);
    NSString *dateS;
    dateS = [formatter stringFromDate:[NSDate date]];
    self.datePicker.date = [formatter dateFromString:dateS];
  }
   
  if ([mode isEqualToString:@"date"]) {
    self.datePicker.datePickerMode = UIDatePickerModeDate;
  }
  else if ([mode isEqualToString:@"time"]) {
    self.datePicker.datePickerMode = UIDatePickerModeTime;
  } else if ([mode isEqualToString:@"duration"]) {
    self.datePicker.datePickerMode = UIDatePickerModeCountDownTimer;
  } else {
    self.datePicker.datePickerMode = UIDatePickerModeDateAndTime;
  }

  if (minuteInterval) {
    self.datePicker.minuteInterval = minuteInterval;
  }

   if (countDownDuration) {
    self.datePicker.countDownDuration = countDownDuration;
  }

   [self.datePicker setValue:[UIColor blackColor] forKey:@"textColor"];
  [self.datePicker setValue:@(false) forKey:@"highlightsToday"];

  if (locale) {
    [self.datePicker setLocale:locale];
  }
}

- (NSDateFormatter *)createISODateFormatter:(NSString *)format timezone:(NSTimeZone *)timezone {
  NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  // Locale needed to avoid formatter bug on phones set to 12-hour
  // time to avoid it adding AM/PM to the string we supply
  // See: http://stackoverflow.com/questions/6613110/what-is-the-best-way-to-deal-with-the-nsdateformatter-locale-feature
  NSLocale *loc = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
  [dateFormatter setLocale: loc];
  [dateFormatter setTimeZone:timezone];
  [dateFormatter setDateFormat:format];
  
  return dateFormatter;
}

- (void)updateCancelButton:(NSMutableDictionary *)options {

  NSString *label = [options objectForKey:@"cancelButtonLabel"];
  [self.cancelButton setTitle:label forState:UIControlStateNormal];
  
  NSString *tintColorHex = [options objectForKey:@"cancelButtonColor"];
  self.cancelButton.tintColor = [self colorFromHexString: tintColorHex];
  
}

- (void)updateDoneButton:(NSMutableDictionary *)options {
  
  NSString *label = [options objectForKey:@"doneButtonLabel"];
  [self.doneButton setTitle:label forState:UIControlStateNormal];
  
  NSString *tintColorHex = [options objectForKey:@"doneButtonColor"];
  [self.doneButton setTintColor: [self colorFromHexString: tintColorHex]];
  
}


#pragma mark - Utilities

/*! Converts a hex string into UIColor
 It based on http://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string
 
  @param hexString The hex string which has to be converted
 */
- (UIColor *)colorFromHexString:(NSString *)hexString {
  unsigned rgbValue = 0;
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
  [scanner setScanLocation:1]; // bypass '#' character
  [scanner scanHexInt:&rgbValue];
  return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
}

@end
