/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2025 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import "Toolbar.h"
#import "EventData.h"
#import "image.h"
#import "menu.h"
#import <objc/runtime.h>

#include "../common/toolbar.h"


void ui_toolbar_init(void) {
    
}



/* ---------------------      UiToolbar      --------------------- */

@implementation UiToolbar

- (UiToolbar*) initWithWindow:(MainWindow*)window {
    self = [super initWithIdentifier:@"UiToolbar"];
    _window = window;
    _obj = window.obj;
    
    allowedItems = [[NSMutableArray alloc]initWithCapacity:16];
    defaultItems = [[NSMutableArray alloc]initWithCapacity:16];
    
    if(window.sidebar) {
        [allowedItems addObject:@"sidebar_separator"];
    }
    if(window.leftPanel) {
        [allowedItems addObject:@"splitview_separator"];
    }
    
    CxMap *toolbarItems = uic_get_toolbar_items();
    CxMapIterator i = cxMapIteratorKeys(toolbarItems);
    cx_foreach(CxHashKey *, key, i) {
        NSString *s = [[NSString alloc]initWithBytes:key->data length:key->len encoding:NSUTF8StringEncoding];
        [allowedItems addObject:s];
    }
    [allowedItems addObject: NSToolbarFlexibleSpaceItemIdentifier];
    [allowedItems addObject: NSToolbarSpaceItemIdentifier];
    
    // UI_TOOLBAR_LEFT = 0,
    // UI_TOOLBAR_CENTER,
    // UI_TOOLBAR_RIGHT,
    // UI_TOOLBAR_SIDEBAR_LEFT,
    // UI_TOOLBAR_SIDEBAR_RIGHT,
    // UI_TOOLBAR_RIGHTPANEL_LEFT,
    // UI_TOOLBAR_RIGHTPANEL_CENTER,
    // UI_TOOLBAR_RIGHTPANEL_RIGHT
    CxList *tbitems[8];
    for(int i=0;i<8;i++) {
        tbitems[i] = uic_get_toolbar_defaults(i);
    }
    
    if(window.sidebar) {
        CxIterator iter = cxListIterator(tbitems[UI_TOOLBAR_SIDEBAR_LEFT]);
        cx_foreach(char *, name, iter) {
            NSString *s = [[NSString alloc] initWithUTF8String:name];
            [defaultItems addObject:s];
        }
        
        CxList *sidebarRight = tbitems[UI_TOOLBAR_SIDEBAR_RIGHT];
        if(cxListSize(sidebarRight) > 0) {
            [defaultItems addObject:NSToolbarFlexibleSpaceItemIdentifier];
            iter = cxListIterator(sidebarRight);
            cx_foreach(char *, name, iter) {
                NSString *s = [[NSString alloc] initWithUTF8String:name];
                [defaultItems addObject:s];
            }
        }
        
        [defaultItems addObject:@"sidebar_separator"];
    }
    
    int start_pos = UI_TOOLBAR_LEFT;
    for(int x=0;x<2;x++) {
        for(int t=start_pos;t<start_pos+3;t++) {
            CxIterator iter = cxListIterator(tbitems[t]);
            cx_foreach(char *, name, iter) {
                NSString *s = [[NSString alloc] initWithUTF8String:name];
                [defaultItems addObject:s];
            }
            if(t < start_pos+2 && cxListSize(tbitems[t+1]) > 0) {
                [defaultItems addObject:NSToolbarFlexibleSpaceItemIdentifier];
            }
        }
        
        if(x == 0 && window.rightPanel) {
            [defaultItems addObject:@"splitview_separator"];
        }
        start_pos = UI_TOOLBAR_RIGHTPANEL_LEFT;
    }
    
    
    [self setDelegate:self];
    [self setAllowsUserCustomization:YES];
    return self;
}

// implementation of NSToolbarDelegate methods

- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
    return allowedItems;
}

- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
    return defaultItems;
}

- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar
  itemForItemIdentifier:(NSString *)itemIdentifier
  willBeInsertedIntoToolbar:(BOOL)flag {
    CxMap *items = uic_get_toolbar_items();
    UiToolbarItemI *item = cxMapGet(items, itemIdentifier.UTF8String);
    if(!item) {
        if([itemIdentifier isEqualToString:@"sidebar_separator"]) {
            NSTrackingSeparatorToolbarItem *sep = [NSTrackingSeparatorToolbarItem trackingSeparatorToolbarItemWithIdentifier:itemIdentifier
                                                                                                                   splitView:_window.splitview
                                                                                                                dividerIndex:0];
            return sep;
        } else if([itemIdentifier isEqualToString:@"splitview_separator"]) {
            int dividerIndex = _window.sidebar != nil ? 1 : 0;
            NSTrackingSeparatorToolbarItem *sep = [NSTrackingSeparatorToolbarItem trackingSeparatorToolbarItemWithIdentifier:itemIdentifier
                                                                                                                   splitView:_window.splitview
                                                                                                                dividerIndex:dividerIndex];
            return sep;
        }
        return nil;
    }
    
    switch(item->type) {
        default: return nil;
        case UI_TOOLBAR_ITEM: {
            return ui_nstoolbaritem_create_item(_obj, (UiToolbarItem*)item, itemIdentifier);
        }
        case UI_TOOLBAR_TOGGLEITEM: {
            return ui_nstoolbaritem_create_toggle(_obj, (UiToolbarToggleItem*)item, itemIdentifier);
        }
        case UI_TOOLBAR_MENU: {
            return ui_nstoolbaritem_create_menu(_obj, (UiToolbarMenuItem*)item, itemIdentifier);
        }
    }
    
    return nil;
}

@end

@implementation UiToolbarToggleEventHandler

- (UiToolbarToggleEventHandler*)init {
    return self;
}

- (void)handleEvent:(id)sender {
    if(_callback == nil) {
        return;
    }
    
    UiEvent event;
    event.obj = _obj;
    event.window = event.obj->window;
    event.document = event.obj->ctx->document;
    event.eventdata = NULL;
    event.eventdatatype = 0;
    event.intval = 0;
    event.set = ui_get_setop();
    
    if([sender isKindOfClass:[NSSegmentedControl class]]) {
        NSSegmentedControl *seg = (NSSegmentedControl*)sender;
        event.intval = [seg isSelectedForSegment:0];
    }
    
    _callback(&event, _userdata);
}

@end

NSToolbarItem* ui_nstoolbaritem_create_item(UiObject *obj, UiToolbarItem *item, NSString *identifier) {
    NSToolbarItem *button = [[NSToolbarItem alloc] initWithItemIdentifier: identifier];
    button.bordered = YES;
    
    if(item->args.label) {
        NSString *label = [[NSString alloc] initWithUTF8String:item->args.label];
        button.paletteLabel = label;
        button.label = label;
    }
    if(item->args.icon) {
        button.image = ui_cocoa_named_icon(item->args.icon);
    }
    
    if(item->args.onclick) {
        EventData *event = [[EventData alloc] init:item->args.onclick userdata:item->args.onclickdata action:item->args.action];
        event.obj = obj;
        button.target = event;
        button.action = @selector(handleEvent:);
        objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
    }
    return button;
}

NSToolbarItem* ui_nstoolbaritem_create_toggle(UiObject *obj, UiToolbarToggleItem *item, NSString *identifier) {
    UiToolbarToggleEventHandler *event = [[UiToolbarToggleEventHandler alloc]init];
    event.obj = obj;
    event.callback = item->args.onchange;
    event.userdata = item->args.onchangedata;
    
    NSToolbarItem *button = [[NSToolbarItem alloc] initWithItemIdentifier:identifier];
    if(item->args.label) {
        NSString *label = [[NSString alloc] initWithUTF8String:item->args.label];
        button.paletteLabel = label;
        button.label = label;
    }
    objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
    
    NSSegmentedControl *seg;
    if(!item->args.icon) {
        NSArray *labels = @[[[NSString alloc] initWithUTF8String:item->args.label]];
        seg = [NSSegmentedControl segmentedControlWithLabels:labels trackingMode:NSSegmentSwitchTrackingSelectAny target:event action:@selector(handleEvent:)];
        button.view = seg;
    } else {
        NSArray *images = @[ui_cocoa_named_icon(item->args.icon)];
        seg = [NSSegmentedControl segmentedControlWithImages:images trackingMode:NSSegmentSwitchTrackingSelectAny target:event action:@selector(handleEvent:)];
    }
    button.view = seg;
    
    UiVar* var = uic_widget_var(obj->ctx, obj->ctx, NULL, item->args.varname, UI_VAR_INTEGER);
    if(var) {
        event.var = var;
        UiInteger *i = var->value;
        if(i->get) {
            if(ui_get(i) != 0) {
                [seg setEnabled:YES forSegment:0];
            }
            
        }
        i->obj = (__bridge void*)seg;
        printf("seg: %p\n", seg);
        i->get = ui_toolbar_seg_toggleitem_get;
        i->set = ui_toolbar_seg_toggleitem_set;
    }
    
    return button;
}

int64_t ui_toolbar_seg_toggleitem_get(UiInteger *i) {
    NSSegmentedControl *seg = (__bridge NSSegmentedControl*)i->obj;
    i->value = [seg isSelectedForSegment:0];
    return i->value;
}

void ui_toolbar_seg_toggleitem_set(UiInteger *i, int64_t value) {
    NSSegmentedControl *seg = (__bridge NSSegmentedControl*)i->obj;
    i->value = value;
    [seg setSelected:value != 0 forSegment:0];
}

NSToolbarItem* ui_nstoolbaritem_create_menu(UiObject *obj, UiToolbarMenuItem *item, NSString *identifier) {
    NSMenuToolbarItem *button = [[NSMenuToolbarItem alloc] initWithItemIdentifier: identifier];
    button.bordered = YES;
    
    if(item->args.label) {
        NSString *label = [[NSString alloc] initWithUTF8String:item->args.label];
        button.paletteLabel = label;
        button.label = label;
    }
    if(item->args.icon) {
        button.image = ui_cocoa_named_icon(item->args.icon);
    }
    
    NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
    ui_add_menu_items(obj, menu, 0, &item->menu);
    
    button.menu = menu;
    
    return button;
}
