/*
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */

#import "CDVGlobalization.h"

@implementation CDVGlobalization

- (void)pluginInitialize
{
    currentLocale = CFLocaleCopyCurrent();
}

- (void)getPreferredLanguage:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* result = nil;

    // Source: http://stackoverflow.com/questions/3910244/getting-current-device-language-in-ios
    // (should be OK)
    NSString* language = [[NSLocale preferredLanguages] objectAtIndex:0];

    if (language) {
        //Format to match other devices
        if(language.length <= 2) {
            NSLocale* locale = [NSLocale currentLocale];
            NSString* localeId = [locale localeIdentifier];
            NSRange underscoreIndex = [localeId rangeOfString:@"_" options:NSBackwardsSearch];
            NSRange atSignIndex = [localeId rangeOfString:@"@"];
            if (underscoreIndex.location != NSNotFound) {
                //If localeIdentifier did not contain @, i.e. did not have calendar other than Gregoarian selected
                if(atSignIndex.length == 0)
                    language = [NSString stringWithFormat:@"%@%@", language, [localeId substringFromIndex:underscoreIndex.location]];
                else {
                    NSRange localeRange = NSMakeRange(underscoreIndex.location, atSignIndex.location-underscoreIndex.location);
                    language = [NSString stringWithFormat:@"%@%@", language, [localeId substringWithRange:localeRange]];
                }
            }
        }
        
        language = [language stringByReplacingOccurrencesOfString:@"_" withString:@"-"];

        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:language forKey:@"value"];

        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
                               messageAsDictionary:dictionary];
    } else {
        // TBD is this ever expected to happen?
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unknown error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
}

- (void)getLocaleName:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* result = nil;
    NSDictionary* dictionary = nil;

    NSLocale* locale = [NSLocale currentLocale];

    if (locale) {
        NSString *localeIdentifier = [[locale localeIdentifier] stringByReplacingOccurrencesOfString:@"_" withString:@"-"];

        dictionary = [NSDictionary dictionaryWithObject:localeIdentifier forKey:@"value"];

        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    } else {
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unknown error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
}

- (void)dateToString:(CDVInvokedUrlCommand*)command
{
    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
    NSDate* date = nil;
    NSString* dateString = nil;
    CDVPluginResult* result = nil;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    id milliseconds = [options valueForKey:@"date"];

    if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]) {
        // get the number of seconds since 1970 and create the date object
        date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue] / 1000];
    }

    // see if any options have been specified
    id items = [options valueForKey:@"options"];
    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
        NSEnumerator* enumerator = [items keyEnumerator];
        id key;

        // iterate through all the options
        while ((key = [enumerator nextObject])) {
            id item = [items valueForKey:key];

            // make sure that only string values are present
            if ([item isKindOfClass:[NSString class]]) {
                // get the desired format length
                if ([key isEqualToString:@"formatLength"]) {
                    if ([item isEqualToString:@"short"]) {
                        style = kCFDateFormatterShortStyle;
                    } else if ([item isEqualToString:@"medium"]) {
                        style = kCFDateFormatterMediumStyle;
                    } else if ([item isEqualToString:@"long"]) {
                        style = kCFDateFormatterLongStyle;
                    } else if ([item isEqualToString:@"full"]) {
                        style = kCFDateFormatterFullStyle;
                    }
                }
                // get the type of date and time to generate
                else if ([key isEqualToString:@"selector"]) {
                    if ([item isEqualToString:@"date"]) {
                        dateStyle = style;
                        timeStyle = kCFDateFormatterNoStyle;
                    } else if ([item isEqualToString:@"time"]) {
                        dateStyle = kCFDateFormatterNoStyle;
                        timeStyle = style;
                    } else if ([item isEqualToString:@"date and time"]) {
                        dateStyle = style;
                        timeStyle = style;
                    }
                }
            }
        }
    }

    // create the formatter using the user's current default locale and formats for dates and times
    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
            currentLocale,
            dateStyle,
            timeStyle);
    // if we have a valid date object then call the formatter
    if (date) {
        dateString = (__bridge_transfer NSString*)CFDateFormatterCreateStringWithDate(kCFAllocatorDefault,
                formatter,
                (__bridge CFDateRef)date);
    }

    // if the date was converted to a string successfully then return the result
    if (dateString) {
        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dateString forKey:@"value"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        // DLog(@"GlobalizationCommand dateToString unable to format %@", [date description]);
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"];
        [dictionary setValue:@"Formatting error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];

    CFRelease(formatter);
}

- (void)stringToDate:(CDVInvokedUrlCommand*)command
{
    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
    CDVPluginResult* result = nil;
    NSString* dateString = nil;
    NSDateComponents* comps = nil;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    // get the string that is to be parsed for a date
    id ms = [options valueForKey:@"dateString"];

    if (ms && [ms isKindOfClass:[NSString class]]) {
        dateString = ms;
    }

    // see if any options have been specified
    id items = [options valueForKey:@"options"];
    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
        NSEnumerator* enumerator = [items keyEnumerator];
        id key;

        // iterate through all the options
        while ((key = [enumerator nextObject])) {
            id item = [items valueForKey:key];

            // make sure that only string values are present
            if ([item isKindOfClass:[NSString class]]) {
                // get the desired format length
                if ([key isEqualToString:@"formatLength"]) {
                    if ([item isEqualToString:@"short"]) {
                        style = kCFDateFormatterShortStyle;
                    } else if ([item isEqualToString:@"medium"]) {
                        style = kCFDateFormatterMediumStyle;
                    } else if ([item isEqualToString:@"long"]) {
                        style = kCFDateFormatterLongStyle;
                    } else if ([item isEqualToString:@"full"]) {
                        style = kCFDateFormatterFullStyle;
                    }
                }
                // get the type of date and time to generate
                else if ([key isEqualToString:@"selector"]) {
                    if ([item isEqualToString:@"date"]) {
                        dateStyle = style;
                        timeStyle = kCFDateFormatterNoStyle;
                    } else if ([item isEqualToString:@"time"]) {
                        dateStyle = kCFDateFormatterNoStyle;
                        timeStyle = style;
                    } else if ([item isEqualToString:@"date and time"]) {
                        dateStyle = style;
                        timeStyle = style;
                    }
                }
            }
        }
    }

    // get the user's default settings for date and time formats
    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
            currentLocale,
            dateStyle,
            timeStyle);

    // set the parsing to be more lenient
    CFDateFormatterSetProperty(formatter, kCFDateFormatterIsLenient, kCFBooleanTrue);

    // parse tha date and time string
    CFDateRef date = CFDateFormatterCreateDateFromString(kCFAllocatorDefault,
            formatter,
            (__bridge CFStringRef)dateString,
            NULL);

    // if we were able to parse the date then get the date and time components
    if (date != NULL) {
        NSCalendar* calendar = [NSCalendar currentCalendar];

        unsigned unitFlags = NSCalendarUnitYear |
            NSCalendarUnitMonth |
            NSCalendarUnitDay |
            NSCalendarUnitHour |
            NSCalendarUnitMinute |
            NSCalendarUnitSecond;

        comps = [calendar components:unitFlags fromDate:(__bridge NSDate*)date];
        CFRelease(date);
    }

    // put the various elements of the date and time into a dictionary
    if (comps != nil) {
        NSArray* keys = [NSArray arrayWithObjects:@"year", @"month", @"day", @"hour", @"minute", @"second", @"millisecond", nil];
        NSArray* values = [NSArray arrayWithObjects:[NSNumber numberWithInteger:[comps year]],
            [NSNumber numberWithInteger:[comps month] - 1],
            [NSNumber numberWithInteger:[comps day]],
            [NSNumber numberWithInteger:[comps hour]],
            [NSNumber numberWithInteger:[comps minute]],
            [NSNumber numberWithInteger:[comps second]],
            [NSNumber numberWithInteger:0],                /* iOS does not provide milliseconds */
            nil];

        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        // Dlog(@"GlobalizationCommand stringToDate unable to parse %@", dateString);
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"];
        [dictionary setValue:@"unable to parse" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];

    CFRelease(formatter);
}

- (void)getDatePattern:(CDVInvokedUrlCommand*)command
{
    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
    CDVPluginResult* result = nil;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    // see if any options have been specified
    id items = [options valueForKey:@"options"];

    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
        NSEnumerator* enumerator = [items keyEnumerator];
        id key;

        // iterate through all the options
        while ((key = [enumerator nextObject])) {
            id item = [items valueForKey:key];

            // make sure that only string values are present
            if ([item isKindOfClass:[NSString class]]) {
                // get the desired format length
                if ([key isEqualToString:@"formatLength"]) {
                    if ([item isEqualToString:@"short"]) {
                        style = kCFDateFormatterShortStyle;
                    } else if ([item isEqualToString:@"medium"]) {
                        style = kCFDateFormatterMediumStyle;
                    } else if ([item isEqualToString:@"long"]) {
                        style = kCFDateFormatterLongStyle;
                    } else if ([item isEqualToString:@"full"]) {
                        style = kCFDateFormatterFullStyle;
                    }
                }
                // get the type of date and time to generate
                else if ([key isEqualToString:@"selector"]) {
                    if ([item isEqualToString:@"date"]) {
                        dateStyle = style;
                        timeStyle = kCFDateFormatterNoStyle;
                    } else if ([item isEqualToString:@"time"]) {
                        dateStyle = kCFDateFormatterNoStyle;
                        timeStyle = style;
                    } else if ([item isEqualToString:@"date and time"]) {
                        dateStyle = style;
                        timeStyle = style;
                    }
                }
            }
        }
    }

    // get the user's default settings for date and time formats
    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
            currentLocale,
            dateStyle,
            timeStyle);

    // get the date pattern to apply when formatting and parsing
    CFStringRef datePattern = CFDateFormatterGetFormat(formatter);
    // get the user's current time zone information
    CFTimeZoneRef timezone = (CFTimeZoneRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterTimeZone);

    // put the pattern and time zone information into the dictionary
    if ((datePattern != nil) && (timezone != nil)) {
        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"timezone", @"iana_timezone", @"utc_offset", @"dst_offset", nil];
        NSArray* values = [NSArray arrayWithObjects:((__bridge NSString*)datePattern),
            [((__bridge NSTimeZone*)timezone)abbreviation],
            [((__bridge NSTimeZone*)timezone)name],
            [NSNumber numberWithLong:[((__bridge NSTimeZone*)timezone)secondsFromGMT]],
            [NSNumber numberWithDouble:[((__bridge NSTimeZone*)timezone)daylightSavingTimeOffset]],
            nil];

        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Pattern error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];

    if (timezone) {
        CFRelease(timezone);
    }
    CFRelease(formatter);
}

- (void)getDateNames:(CDVInvokedUrlCommand*)command
{
    int style = CDV_FORMAT_LONG;
    int selector = CDV_SELECTOR_MONTHS;
    CFStringRef dataStyle = kCFDateFormatterMonthSymbols;
    CDVPluginResult* result = nil;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    // see if any options have been specified
    id items = [options valueForKey:@"options"];

    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
        NSEnumerator* enumerator = [items keyEnumerator];
        id key;

        // iterate through all the options
        while ((key = [enumerator nextObject])) {
            id item = [items valueForKey:key];

            // make sure that only string values are present
            if ([item isKindOfClass:[NSString class]]) {
                // get the desired type of name
                if ([key isEqualToString:@"type"]) {
                    if ([item isEqualToString:@"narrow"]) {
                        style = CDV_FORMAT_SHORT;
                    } else if ([item isEqualToString:@"wide"]) {
                        style = CDV_FORMAT_LONG;
                    }
                }
                // determine if months or days are needed
                else if ([key isEqualToString:@"item"]) {
                    if ([item isEqualToString:@"months"]) {
                        selector = CDV_SELECTOR_MONTHS;
                    } else if ([item isEqualToString:@"days"]) {
                        selector = CDV_SELECTOR_DAYS;
                    }
                }
            }
        }
    }

    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
            currentLocale,
            kCFDateFormatterFullStyle,
            kCFDateFormatterFullStyle);

    if ((selector == CDV_SELECTOR_MONTHS) && (style == CDV_FORMAT_LONG)) {
        dataStyle = kCFDateFormatterMonthSymbols;
    } else if ((selector == CDV_SELECTOR_MONTHS) && (style == CDV_FORMAT_SHORT)) {
        dataStyle = kCFDateFormatterShortMonthSymbols;
    } else if ((selector == CDV_SELECTOR_DAYS) && (style == CDV_FORMAT_LONG)) {
        dataStyle = kCFDateFormatterWeekdaySymbols;
    } else if ((selector == CDV_SELECTOR_DAYS) && (style == CDV_FORMAT_SHORT)) {
        dataStyle = kCFDateFormatterShortWeekdaySymbols;
    }

    CFArrayRef names = (CFArrayRef)CFDateFormatterCopyProperty(formatter, dataStyle);

    if (names) {
        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:((__bridge NSArray*)names) forKey:@"value"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
        CFRelease(names);
    }
    // error
    else {
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unknown error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];

    CFRelease(formatter);
}

- (void)isDayLightSavingsTime:(CDVInvokedUrlCommand*)command
{
    NSDate* date = nil;
    CDVPluginResult* result = nil;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    id milliseconds = [options valueForKey:@"date"];

    if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]) {
        // get the number of seconds since 1970 and create the date object
        date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue] / 1000];
    }

    if (date) {
        // get the current calendar for the user and check if the date is using DST
        NSCalendar* calendar = [NSCalendar currentCalendar];
        NSTimeZone* timezone = [calendar timeZone];
        NSNumber* dst = [NSNumber numberWithBool:[timezone isDaylightSavingTimeForDate:date]];

        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dst forKey:@"dst"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unknown error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }
    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
}

- (void)getFirstDayOfWeek:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* result = nil;

    NSCalendar* calendar = [NSCalendar autoupdatingCurrentCalendar];

    NSNumber* day = [NSNumber numberWithInteger:[calendar firstWeekday]];

    if (day) {
        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:day forKey:@"value"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unknown error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
}

- (void)numberToString:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* result = nil;
    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
    NSNumber* number = nil;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    id value = [options valueForKey:@"number"];

    if (value && [value isKindOfClass:[NSNumber class]]) {
        number = (NSNumber*)value;
    }

    // see if any options have been specified
    id items = [options valueForKey:@"options"];
    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
        NSEnumerator* enumerator = [items keyEnumerator];
        id key;

        // iterate through all the options
        while ((key = [enumerator nextObject])) {
            id item = [items valueForKey:key];

            // make sure that only string values are present
            if ([item isKindOfClass:[NSString class]]) {
                // get the desired style of formatting
                if ([key isEqualToString:@"type"]) {
                    if ([item isEqualToString:@"percent"]) {
                        style = kCFNumberFormatterPercentStyle;
                    } else if ([item isEqualToString:@"currency"]) {
                        style = kCFNumberFormatterCurrencyStyle;
                    } else if ([item isEqualToString:@"decimal"]) {
                        style = kCFNumberFormatterDecimalStyle;
                    }
                }
            }
        }
    }

    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
            currentLocale,
            style);

    // get the localized string based upon the locale and user preferences
    NSString* numberString = (__bridge_transfer NSString*)CFNumberFormatterCreateStringWithNumber(kCFAllocatorDefault,
            formatter,
            (__bridge CFNumberRef)number);

    if (numberString) {
        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:numberString forKey:@"value"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        // DLog(@"GlobalizationCommand numberToString unable to format %@", [number stringValue]);
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unable to format" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];

    CFRelease(formatter);
}

- (void)stringToNumber:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* result = nil;
    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
    NSString* numberString = nil;
    double doubleValue;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    id value = [options valueForKey:@"numberString"];

    if (value && [value isKindOfClass:[NSString class]]) {
        numberString = (NSString*)value;
    }

    // see if any options have been specified
    id items = [options valueForKey:@"options"];
    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
        NSEnumerator* enumerator = [items keyEnumerator];
        id key;

        // iterate through all the options
        while ((key = [enumerator nextObject])) {
            id item = [items valueForKey:key];

            // make sure that only string values are present
            if ([item isKindOfClass:[NSString class]]) {
                // get the desired style of formatting
                if ([key isEqualToString:@"type"]) {
                    if ([item isEqualToString:@"percent"]) {
                        style = kCFNumberFormatterPercentStyle;
                    } else if ([item isEqualToString:@"currency"]) {
                        style = kCFNumberFormatterCurrencyStyle;
                    } else if ([item isEqualToString:@"decimal"]) {
                        style = kCFNumberFormatterDecimalStyle;
                    }
                }
            }
        }
    }

    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
            currentLocale,
            style);

    // we need to make this lenient so as to avoid problems with parsing currencies that have non-breaking space characters
    if (style == kCFNumberFormatterCurrencyStyle) {
        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterIsLenient, kCFBooleanTrue);
    }

    // parse againist the largest type to avoid data loss
    Boolean rc = CFNumberFormatterGetValueFromString(formatter,
            (__bridge CFStringRef)numberString,
            NULL,
            kCFNumberDoubleType,
            &doubleValue);

    if (rc) {
        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:doubleValue] forKey:@"value"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        // DLog(@"GlobalizationCommand stringToNumber unable to parse %@", numberString);
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unable to parse" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];

    CFRelease(formatter);
}

- (void)getNumberPattern:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* result = nil;
    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
    CFStringRef symbolType = NULL;
    NSString* symbol = @"";

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    // see if any options have been specified
    id items = [options valueForKey:@"options"];

    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
        NSEnumerator* enumerator = [items keyEnumerator];
        id key;

        // iterate through all the options
        while ((key = [enumerator nextObject])) {
            id item = [items valueForKey:key];

            // make sure that only string values are present
            if ([item isKindOfClass:[NSString class]]) {
                // get the desired style of formatting
                if ([key isEqualToString:@"type"]) {
                    if ([item isEqualToString:@"percent"]) {
                        style = kCFNumberFormatterPercentStyle;
                    } else if ([item isEqualToString:@"currency"]) {
                        style = kCFNumberFormatterCurrencyStyle;
                    } else if ([item isEqualToString:@"decimal"]) {
                        style = kCFNumberFormatterDecimalStyle;
                    }
                }
            }
        }
    }

    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
            currentLocale,
            style);

    NSString* numberPattern = (__bridge NSString*)CFNumberFormatterGetFormat(formatter);

    if (style == kCFNumberFormatterCurrencyStyle) {
        symbolType = kCFNumberFormatterCurrencySymbol;
    } else if (style == kCFNumberFormatterPercentStyle) {
        symbolType = kCFNumberFormatterPercentSymbol;
    }

    if (symbolType) {
        symbol = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, symbolType);
    }

    NSString* decimal = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterDecimalSeparator);
    NSString* grouping = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterGroupingSeparator);
    NSString* posSign = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterPlusSign);
    NSString* negSign = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinusSign);
    NSNumber* fracDigits = (__bridge_transfer NSNumber*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinFractionDigits);
    NSNumber* roundingDigits = (__bridge_transfer NSNumber*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterRoundingIncrement);

    // put the pattern information into the dictionary
    if (numberPattern != nil) {
        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"symbol", @"fraction", @"rounding",
            @"positive", @"negative", @"decimal", @"grouping", nil];
        NSArray* values = [NSArray arrayWithObjects:numberPattern, symbol, fracDigits, roundingDigits,
            posSign, negSign, decimal, grouping, nil];
        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
    }
    // error
    else {
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Pattern error" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];

    CFRelease(formatter);
}

- (void)getCurrencyPattern:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* result = nil;
    NSString* currencyCode = nil;
    NSString* numberPattern = nil;
    NSString* decimal = nil;
    NSString* grouping = nil;
    int32_t defaultFractionDigits;
    double roundingIncrement;
    Boolean rc;

    NSDictionary* options;

    if ([command.arguments count] > 0) {
        options = [command argumentAtIndex:0];
    }
    if (!options) {
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
        return;
    }

    id value = [options valueForKey:@"currencyCode"];

    if (value && [value isKindOfClass:[NSString class]]) {
        currencyCode = (NSString*)value;
    }

    // first see if there is base currency info available and fill in the currency_info structure
    rc = CFNumberFormatterGetDecimalInfoForCurrencyCode((__bridge CFStringRef)currencyCode, &defaultFractionDigits, &roundingIncrement);

    // now set the currency code in the formatter
    if (rc) {
        CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
                currentLocale,
                kCFNumberFormatterCurrencyStyle);

        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterCurrencyCode, (__bridge CFStringRef)currencyCode);
        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterInternationalCurrencySymbol, (__bridge CFStringRef)currencyCode);

        numberPattern = (__bridge NSString*)CFNumberFormatterGetFormat(formatter);
        decimal = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyDecimalSeparator);
        grouping = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyGroupingSeparator);

        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"code", @"fraction", @"rounding",
            @"decimal", @"grouping", nil];
        NSArray* values = [NSArray arrayWithObjects:numberPattern, currencyCode, [NSNumber numberWithInt:defaultFractionDigits],
            [NSNumber numberWithDouble:roundingIncrement], decimal, grouping, nil];
        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
        CFRelease(formatter);
    }
    // error
    else {
        // DLog(@"GlobalizationCommand getCurrencyPattern unable to get pattern for %@", currencyCode);
        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
        [dictionary setValue:@"Unable to get pattern" forKey:@"message"];
        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
    }

    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
}

- (void)dealloc
{
    if (currentLocale) {
        CFRelease(currentLocale);
        currentLocale = nil;
    }
}

@end
