/*---------------------------------------------------------------------------*/
/* Forms.m                                                                   */
/* copyright (c) innovaphone 2015                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#import "platform/platform.h"
#import "platform/IosNamespace.h"
#import "FormsConst.h"

@interface Forms()

@property (nonatomic) NSMutableArray *obj_table;
@property (nonatomic) int id_free;
@property (nonatomic) NSMutableArray *id_obj_table;
@property (nonatomic) int change_localized_texts_index;

@end
@implementation Forms

- (void) forms_create:(IosAsync *)ios_async
{
}

- (void) event_headset_plugged_:(bool)plugged
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"DSP/HEADSET-PLUGGED", plugged ? @"1" : @"0");
}

- (void) event_headset_hook_
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"DSP/HEADSET-HOOK", @"");
}

- (void) event_dial_number_:(NSString *)number name:(NSString *)name video_mode:(int)video_mode
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"PHONE/DIAL-NUMBER", [NSString stringWithFormat:@"%@\n%@\n%d", number, (name != nil) ? name : @"", video_mode]);
}

- (void) event_dial_sip_:(NSString *)sip name:(NSString *)name video_mode:(int)video_mode
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"PHONE/DIAL-SIP", [NSString stringWithFormat:@"%@\n%@\n%d", sip, (name != nil) ? name : @"", video_mode]);
}

- (void) event_start_chat_:(NSString *)sip
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"PHONE/START-CHAT", sip);
}

- (void) event_transfer_to_number_:(NSString *)number
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"PHONE/TRANSFER-TO-NUMBER", number);
}

- (void) event_pbx_innovaphone_data_mobility_:(NSString *)xml
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"PHONE/PBX-INNOVAPHONE-DATA-MOBILITY", xml);
}

- (void) event_pause_subscriptions_:(bool)pause
{
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"PHONE/PAUSE-SUBSCRIPTIONS", pause ? @"1" : @"0");
}

- (void) event_push_token_:(NSData *)token token_voip:(NSData *)token_voip
{
static char hex_digit_table[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
    char token_buffer[512];
    bool production;
    int i, l;
    word app_id;

#ifdef DEBUG
    production = false;
#else
    production = ![[[[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:nil
        ofType:@"entitlements"]] objectForKey:@"aps-environment"] isEqualToString:@"development"];
#endif
    l = 0;
    if (token_voip != nil) {
        app_id = production ? 73 : 74;
        token_buffer[l++] = hex_digit_table[app_id >> 12];
        token_buffer[l++] = hex_digit_table[(app_id >> 8) & 0xf];
        token_buffer[l++] = hex_digit_table[(app_id >> 4) & 0xf];
        token_buffer[l++] = hex_digit_table[app_id & 0xf];
        for (i = 0; i < token_voip.length; i++) {
            token_buffer[l++] = hex_digit_table[((byte *)(token_voip.bytes))[i] >> 4];
            token_buffer[l++] = hex_digit_table[((byte *)(token_voip.bytes))[i] & 0xf];
        }
    }
    if (token != nil) {
        if (token_voip != nil) {
            token_buffer[l++] = ' ';
        }
#if TARGET_OS_IPHONE
        app_id = production ? 71 : 72;
#else
        app_id = production ? 76 : 77;
#endif
        token_buffer[l++] = hex_digit_table[app_id >> 12];
        token_buffer[l++] = hex_digit_table[(app_id >> 8) & 0xf];
        token_buffer[l++] = hex_digit_table[(app_id >> 4) & 0xf];
        token_buffer[l++] = hex_digit_table[app_id & 0xf];
        for (i = 0; i < token.length; i++) {
            token_buffer[l++] = hex_digit_table[((byte *)(token.bytes))[i] >> 4];
            token_buffer[l++] = hex_digit_table[((byte *)(token.bytes))[i] & 0xf];
        }
    }
    token_buffer[l] = '\0';
    self.ios_event.enqueue(FORMS_EVENT_SET_PROPERTY, @"PHONE/PUSH-TOKEN", [NSString stringWithCString:token_buffer encoding:NSUTF8StringEncoding]);
}

- (void) trc_:(NSString *)text
{
    self.ios_event.enqueue(FORMS_EVENT_TRACE, text);
}

- (void) forms_add_localized_text:(IosAsync *)ios_async
{
    [self.localized_texts addObject:ios_async.get_string()];
}

- (void) forms_change_localized_text:(IosAsync *)ios_async
{
    [self.localized_texts replaceObjectAtIndex:self.change_localized_texts_index withObject:ios_async.get_string()];
    self.change_localized_texts_index++;
    if(self.change_localized_texts_index == self.localized_texts.count) {
        self.change_localized_texts_index = 0;
        [self.formsDelegate formsSetLanguage];
    }
}

- (void) forms_set_forms_property:(IosAsync *)ios_async
{
    NSString *name = ios_async.get_string();
    NSString *value = ios_async.get_string();
    [self.formsDelegate formsSetFormsProperty:name value:value];
}

- (void) forms_webserver_started:(IosAsync *)ios_async
{
    NSString *url_to_load = ios_async.get_string();
    NSString *user_agent = ios_async.get_string();
    NSString *webserver_url = ios_async.get_string();
    NSString *start_fix_cert_url = ios_async.get_string();
    [self.formsDelegate formsWebserverStarted:url_to_load user_agent:user_agent webserver_url:webserver_url start_fix_cert_url:start_fix_cert_url];
}

- (void) forms_add_local_notification:(IosAsync *)ios_async
{
    NSString *ref = ios_async.get_string();
    int type = ios_async.get_int();
    NSString *title = ios_async.get_string();
    NSString *text = ios_async.get_string();
    NSString *smallIcon = ios_async.get_string();
    NSString *largeIcon = ios_async.get_string();
    NSString *soundUrl = ios_async.get_string();
    NSString *buttonTitle = ios_async.get_string();
    NSString *acceptTitle = ios_async.get_string();
    NSString *rejectTitle = ios_async.get_string();
    NSString *link = ios_async.get_string();
    [self.formsDelegate formsAddLocalNotification:ref type:type title:title text:text smallIcon:smallIcon largeIcon:largeIcon
        soundUrl:soundUrl buttonTitle:buttonTitle acceptTitle:acceptTitle rejectTitle:rejectTitle link:link];
}

- (void) forms_remove_local_notification:(IosAsync *)ios_async
{
    NSString *ref = ios_async.get_string();
    [self.formsDelegate formsRemoveLocalNotification:ref];
}

- (void) forms_set_focus:(IosAsync *)ios_async
{
    NSString *app = ios_async.get_string();
    NSString *title = ios_async.get_string();
    [self.formsDelegate formsSetFocus:app title:title];
}

- (void) forms_set_resize:(IosAsync *)ios_async
{
    NSString *app = ios_async.get_string();
    int width = ios_async.get_int();
    int height = ios_async.get_int();
    [self.formsDelegate formsSetResize:app width:width height:height];
}

- (void) forms_app_window_opened:(IosAsync *)ios_async
{
    NSString *app = ios_async.get_string();
    NSString *title = ios_async.get_string();
    [self.formsDelegate formsAppWindowOpened:app title:title];
}

- (void) forms_set_autostart:(IosAsync *)ios_async
{
    bool autostart = ios_async.get_bool();
    [self.formsDelegate formsSetAutostart:autostart];
}

- (void) forms_set_offline:(IosAsync *)ios_async
{
    int offline = ios_async.get_int();
    [self.formsDelegate formsSetOffline:offline];
}

- (void) forms_set_hotkey:(IosAsync *)ios_async
{
    int type = ios_async.get_int();
    NSString *hotkey = ios_async.get_string();
    [self.formsDelegate formsSetHotkey:type hotkey:hotkey];
}

- (void) forms_set_desktop_notifications:(IosAsync *)ios_async
{
    bool show = ios_async.get_bool();
    [self.formsDelegate formsSetDesktopNotifications:show];
}

- (void) forms_start_external_app:(IosAsync *)ios_async
{
    NSString *app = ios_async.get_string();
    NSString *param = ios_async.get_string();
    [self.formsDelegate formsStartExternalApp:app param:param];
}

- (void) forms_set_docking:(IosAsync *)ios_async
{
    int docking = ios_async.get_int();
    [self.formsDelegate formsSetDocking:docking];
}

- (void) forms_set_badge_count:(IosAsync *)ios_async
{
    NSString *ref = ios_async.get_string();
    int count = ios_async.get_int();
    NSString *text = ios_async.get_string();
    [self.formsDelegate formsSetBadgeCount:ref count:count text:text];
}

- (void) forms_detect_webcams:(IosAsync *)ios_async
{
    NSString *context = ios_async.get_string();
    [self.formsDelegate formsDetectWebcams:context];
}

- (void) forms_start_webcam:(IosAsync *)ios_async
{
    NSString *id = ios_async.get_string();
    NSString *context = ios_async.get_string();
    int width = ios_async.get_int();
    int height = ios_async.get_int();
    bool hdVideo = ios_async.get_bool();
    [self.formsDelegate formsStartWebcam:id context:context width:width height:height hdVideo:hdVideo];
}

- (void) forms_keyboard_event:(IosAsync *)ios_async
{
    int code = ios_async.get_int();
    bool keyDown = ios_async.get_bool();
    [self.formsDelegate formsKeyboardEvent:code keyDown:keyDown];
}

- (void) forms_mouse_event:(IosAsync *)ios_async
{
    int x = ios_async.get_int();
    int y = ios_async.get_int();
    bool right = ios_async.get_bool();
    bool keyDown = ios_async.get_bool();
    [self.formsDelegate formsMouseEvent:x y:y right:right keyDown:keyDown];
}

- (void) forms_mouse_wheel_event:(IosAsync *)ios_async
{
    bool direction = ios_async.get_bool();
    [self.formsDelegate formsMouseWheelEvent:direction];
}

- (void) forms_stop_webcam:(IosAsync *)ios_async
{
    NSString *id = ios_async.get_string();
    [self.formsDelegate formsStopWebcam:id];
}

- (void) forms_webcam_full_intra_request:(IosAsync *)ios_async
{
    NSString *id = ios_async.get_string();
    [self.formsDelegate formsWebcamFullIntraRequest:id];
}

- (void) forms_video_transcode:(IosAsync *)ios_async
{
    int transcoder_id = ios_async.get_int();
    int timestamp = ios_async.get_int();
    int duration = ios_async.get_int();
    short sequenceDiff = (short)(ios_async.get_int());
    int length;
    byte *frame = ios_async.get_byte_array(&length, true);
    int width = ios_async.get_int();
    int height = ios_async.get_int();
    int stride = ios_async.get_int();
    int flags = ios_async.get_int();
    int from = ios_async.get_int();
    int to = ios_async.get_int();
    [self.formsDelegate formsVideoTranscode:transcoder_id timestamp:timestamp duration:duration sequenceDiff:sequenceDiff frame:frame length:length width:width height:height stride:stride flags:flags from:from to:to];
}

- (void) forms_contacts_search:(IosAsync *)ios_async
{
    NSString *ref = ios_async.get_string();
    NSString *pattern = ios_async.get_string();
    [self.formsDelegate formsContactsSearch:ref pattern:pattern];
}

- (void) forms_contacts_search_more:(IosAsync *)ios_async
{
    [self.formsDelegate formsContactsSearchMore];
}

- (void) forms_contacts_lookup:(IosAsync *)ios_async
{
    NSString *ref = ios_async.get_string();
    NSString *number = ios_async.get_string();
    NSString *prefixIntl = ios_async.get_string();
    NSString *prefixNtl = ios_async.get_string();
    NSString *prefixSubs = ios_async.get_string();
    NSString *areaCode = ios_async.get_string();
    NSString *countryCode = ios_async.get_string();
    [self.formsDelegate formsContactsLookup:ref number:number prefixIntl:prefixIntl prefixNtl:prefixNtl prefixSubs:prefixSubs areaCode:areaCode countryCode:countryCode];
}

- (void) forms_webserver_get:(IosAsync *)ios_async
{
    NSString *context = ios_async.get_string();
    NSString *resourceName = ios_async.get_string();
    [self.formsDelegate formsWebserverGet:context resourceName:resourceName];
}

- (void) forms_webserver_get_sent:(IosAsync *)ios_async
{
    NSString *context = ios_async.get_string();
    [self.formsDelegate formsWebserverGetSent:context];
}

- (void) forms_cx_use:(IosAsync *)ios_async
{
    bool use = ios_async.get_bool();
    NSString *ringtone = ios_async.get_string();
    bool supportsVideo = ios_async.get_bool();
    int maximumCallGroups = ios_async.get_int();
    int maximumCallsPerCallGroup = ios_async.get_int();
    [self.formsDelegate formsCxUse:use ringtone:ringtone supportsVideo:supportsVideo maximumCallGroups:maximumCallGroups maximumCallsPerCallGroup:maximumCallsPerCallGroup];
}

- (void) forms_cx_report_new_incoming_call:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    NSString *number = ios_async.get_string();
    NSString *name = ios_async.get_string();
    NSString *transfer = ios_async.get_string();
    NSString *called = ios_async.get_string();
    int flags = ios_async.get_int();
    [self.formsDelegate formsCxReportNewIncomingCall:uuid number:number name:name transfer:transfer called:called flags:flags];
}

- (void) forms_cx_report_outgoing_call_connecting:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    [self.formsDelegate formsCxReportOutgoingCallConnecting:uuid];
}

- (void) forms_cx_report_outgoing_call_connected:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    [self.formsDelegate formsCxReportOutgoingCallConnected:uuid];
}

- (void) forms_cx_report_call_updated:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    NSString *number = ios_async.get_string();
    NSString *name = ios_async.get_string();
    NSString *transfer = ios_async.get_string();
    NSString *called = ios_async.get_string();
    int flags = ios_async.get_int();
    [self.formsDelegate formsCxReportCallUpdated:uuid number:number name:name transfer:transfer called:called flags:flags];
}

- (void) forms_cx_report_call_ended:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    int reason = ios_async.get_int();
    [self.formsDelegate formsCxReportCallEnded:uuid reason:reason];
}

- (void) forms_cx_request_start_call:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    NSString *number = ios_async.get_string();
    NSString *name = ios_async.get_string();
    bool video = ios_async.get_bool();
    [self.formsDelegate formsCxRequestStartCall:uuid number:number name:name video:video];
}

- (void) forms_cx_request_end_call:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    [self.formsDelegate formsCxRequestEndCall:uuid];
}

- (void) forms_cx_request_set_held_call:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    bool held = ios_async.get_bool();
    [self.formsDelegate formsCxRequestSetHeldCall:uuid held:held];
}

- (void) forms_cx_request_set_muted_call:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    bool muted = ios_async.get_bool();
    [self.formsDelegate formsCxRequestSetMutedCall:uuid muted:muted];
}

- (void) forms_cx_request_set_group_call:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    NSString *with = ios_async.get_string();
    [self.formsDelegate formsCxRequestSetGroupCall:uuid with:with];
}

- (void) forms_cx_request_play_dtmf:(IosAsync *)ios_async
{
    NSString *uuid = ios_async.get_string();
    NSString *digits = ios_async.get_string();
    [self.formsDelegate formsCxRequestPlayDTMF:uuid digits:digits];
}

- (void) forms_start_screen_capture:(IosAsync *)ios_async
{
    [self.formsDelegate formsStartScreenCapture];
}

- (void) forms_stop_screen_capture:(IosAsync *)ios_async
{
    [self.formsDelegate formsStopScreenCapture];
}

- (void) forms_set_conn_info:(IosAsync *)ios_async
{
    bool up = ios_async.get_bool();
    bool standby = ios_async.get_bool();
    NSString *cur = ios_async.get_string();
    NSString *pri = ios_async.get_string();
    NSString *sec = ios_async.get_string();
    NSString *master = ios_async.get_string();
    [self.formsDelegate formsSetConnInfo:up standby:standby cur:cur pri:pri sec:sec master:master];
}

- (void) event_phonelist_import_:(int)more
{
/*
    int i;
    i = 0;
    while((i < phonelist_import_chunk_size) && more) {
        self.ios_event.enqueue(FORMS_EVENT_PHONELIST_IMPORT, 0,
            FORMS_PHONELIST_INBOUND_MISSED,
            date,
            @"contact number",
            duration,
            @"name",
            is_new);
        i++;
        more = phonelist_cursor.moveToNext();
    }
*/
    self.ios_event.enqueue(FORMS_EVENT_PHONELIST_MORE, 0, more);
}

- (void) forms_phonelist_import:(IosAsync *)ios_async
{
    if(ios_async.get_bool()) { /* first */
        self.event_phonelist_import(-1);
    }
    else {
        self.event_phonelist_import(-1);
    }
}

- (void) forms_phonelist_export:(IosAsync *)ios_async
{
    /* int type = */ (void) ios_async.get_int();
    /* int time = */ (void) ios_async.get_int();
    /* NSString *number = */ (void) ios_async.get_string();
    /* int duration = */ (void) ios_async.get_int();
    /* NSString *name = */ (void) ios_async.get_string();
    /* bool is_new = */ (void) ios_async.get_bool();

}

- (void) forms_phonelist_loop:(IosAsync *)ios_async
{
    self.ios_event.enqueue(FORMS_EVENT_PHONELIST_LOOPED, 0);
}

- (void) forms_phonelist_delete:(IosAsync *)ios_async
{
    /* int type = */ (void) ios_async.get_int();
    /* int time = */ (void) ios_async.get_int();
    /* NSString *number = */ (void) ios_async.get_string();
}

- (void) forms_phonelist_delete_list:(IosAsync *)ios_async
{
    /* int type = */ (void) ios_async.get_int();
    /* int time = */ (void) ios_async.get_int();
    /* NSString *number = */ (void) ios_async.get_string();
    /* int type_mask = */ (void) ios_async.get_int();
}

#if TARGET_OS_IPHONE
- (void) forms_cp_create:(IosAsync *)ios_async
{
    int new_id = ios_async.get_int();
    [self.formsDelegate formsCPCreate:new_id];
}
#endif

- (id) initWithId:(int)new_id ios_event:(IosEvent *)ios_event
{
    self = [super init];
    if (self) {
        Forms *__weak weakSelf = self;
        _new_id = ^ int (FormsObject *obj) {
            int id = weakSelf.id_free;
            if (id == weakSelf.obj_table.count) {
                [weakSelf.obj_table addObject:obj];
                (weakSelf.id_free)++;
            }
            else {
                weakSelf.id_free = ((NSNumber *)(weakSelf.obj_table[id])).intValue;
                weakSelf.obj_table[id] = obj;
            }
            return ~id;
        };
        _free_id = ^ void (int obj_id) { weakSelf.obj_table[~obj_id] = [NSNumber numberWithInt:weakSelf.id_free]; weakSelf.id_free = ~obj_id; };
        _id_obj = ^ FormsObject * (int obj_id) { FormsObject *obj = (FormsObject *)(weakSelf.obj_table[~obj_id]); return ((((NSNull *) obj) == [NSNull null]) ? nil : obj); };
        _set_id_obj = ^ void (int obj_id, FormsObject *obj) {
            while (weakSelf.id_obj_table.count < obj_id) {
                [weakSelf.id_obj_table addObject:[NSNull null]];
            }
            weakSelf.id_obj_table[obj_id] = (obj != nil) ? obj : [NSNull null];
        };
        _get_id_obj = ^ FormsObject * (int obj_id) { FormsObject *obj = (FormsObject *)(weakSelf.id_obj_table[obj_id]); return ((((NSNull *) obj) == [NSNull null]) ? nil : obj); };
        _localized_texts_get = ^ NSString * (int index) { return (NSString *)(weakSelf.localized_texts[index]); };
        _event_headset_plugged = ^ void (bool plugged) { [weakSelf event_headset_plugged_:plugged]; };
        _event_headset_hook = ^ void () { [weakSelf event_headset_hook]; };
        _event_dial_number = ^ void (NSString *number, NSString *name, int video_mode) { [weakSelf event_dial_number_:number name:name video_mode:video_mode]; };
        _event_dial_sip = ^ void (NSString *sip, NSString *name, int video_mode) { [weakSelf event_dial_sip_:sip name:name video_mode:video_mode]; };
        _event_start_chat = ^ void (NSString *sip) { [weakSelf event_start_chat_:sip]; };
        _event_transfer_to_number = ^ void (NSString *number) { [weakSelf event_transfer_to_number_:number]; };
        _event_pbx_innovaphone_data_mobility = ^ void (NSString *xml) { [weakSelf event_pbx_innovaphone_data_mobility_:xml]; };
        _event_pause_subscriptions = ^ void (bool pause) { [weakSelf event_pause_subscriptions_:pause]; };
        _event_push_token = ^ void (NSData *token, NSData *token_voip) { [weakSelf event_push_token_:token token_voip:token_voip]; };
        _trc = ^ void (NSString *text) { [weakSelf trc_:text]; };
        _event_phonelist_import = ^ void (int more) { [weakSelf event_phonelist_import_:more]; };

        _ios_event = ios_event;
        _obj_table = [NSMutableArray array];
        _id_free = 0;
        _id_obj_table = [NSMutableArray array];
        _set_id_obj(new_id, self);
        _localized_texts = [NSMutableArray array];
    }
    return self;
}

+ (id) formsWithId:(int)new_id ios_event:(IosEvent *)ios_event
{
    return [[self alloc] initWithId:new_id ios_event:ios_event];
}

@end
