#include "yacreader_macosx_toolbar.h"
#include "QtWidgets/qmainwindow.h"

#include <QtGlobal>
#include <QtWidgets>

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QWidget>
#include <QMacNativeWidget>
#include <qmacfunctions.h>
#include <qpa/qplatformnativeinterface.h>
#include <QsLog.h>

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

#import "shortcuts_manager.h"

//----------------------------
// A custom items separator for NSToolbar
@interface CustomSeparator : NSView

@end

@implementation CustomSeparator

- (void)drawRect:(NSRect)rect
{
    [[NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:1] setFill];
    NSRectFill(rect);
    [super drawRect:rect];
}

@end

//----------------------------
// Toolbar delegate, needed for allow disabled/enabled items
@interface MyToolbarDelegate : NSObject <NSToolbarDelegate> {
@public
    YACReaderMacOSXToolbar *mytoolbar;
}

- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdent willBeInsertedIntoToolbar:(BOOL)willBeInserted;
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar;
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar;
//- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar;
- (IBAction)itemClicked:(id)sender;
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem;
@end

@implementation MyToolbarDelegate

- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

    NSMutableArray *array = [[NSMutableArray alloc] init];

    QList<QMacToolBarItem *> items = mytoolbar->items();
    foreach (const QMacToolBarItem *item, items) {
        [array addObject:item->nativeToolBarItem().itemIdentifier];
    }
    return array;
}

- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

    NSMutableArray *array = [[NSMutableArray alloc] init];

    QList<QMacToolBarItem *> items = mytoolbar->items();
    foreach (const QMacToolBarItem *item, items) {
        [array addObject:item->nativeToolBarItem().itemIdentifier];
    }
    return array;
}

/*
- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

    NSMutableArray *array = [[NSMutableArray alloc] init];

    QList<QMacToolBarItem *> items = mytoolbar->items();
    foreach (const QMacToolBarItem * item, items) {
        [array addObject : item->nativeToolBarItem().itemIdentifier];
    }
    return array;
    //NSMutableArray *array = toolbarPrivate->getItemIdentifiers(toolbarPrivate->items, true);
    //[array addObjectsFromArray:toolbarPrivate->getItemIdentifiers(toolbarPrivate->allowedItems, true)];
    //return array;
}*/

- (IBAction)itemClicked:(id)sender
{
    if ([sender respondsToSelector:@selector(itemIdentifier)]) {
        NSToolbarItem *item = reinterpret_cast<NSToolbarItem *>(sender);

        QString identifier = QString::fromNSString([item itemIdentifier]);
        QMacToolBarItem *toolButton = reinterpret_cast<QMacToolBarItem *>(identifier.toULongLong());
        Q_EMIT toolButton->activated();
    }
}

- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)willBeInserted
{
    Q_UNUSED(toolbar);
    Q_UNUSED(willBeInserted);
    QList<QMacToolBarItem *> items = mytoolbar->items();

    foreach (const QMacToolBarItem *item, items) {
        NSToolbarItem *toolbarItem = item->nativeToolBarItem();
        if ([toolbarItem.itemIdentifier isEqual:itemIdentifier]) {

            [toolbarItem setTarget:self];
            [toolbarItem setAction:@selector(itemClicked:)];

            return toolbarItem;
        }
    }
    return nil;
}

- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
{
    QString identifier = QString::fromNSString(theItem.itemIdentifier);

    if (mytoolbar->actions.contains(identifier)) {
        return mytoolbar->actions.value(identifier)->isEnabled();
    } else
        return NO;
}
@end

//----------------------------
// detect changes in native text field
// TODO implement validation and auto completion
@interface MyTextFieldDelegate : NSObject <NSTextFieldDelegate> {
@public
    YACReaderMacOSXSearchLineEdit *mylineedit;
}
@end

@implementation MyTextFieldDelegate

- (void)controlTextDidChange:(NSNotification *)notification
{
    NSTextField *textField = [notification object];
    NSLog(@"%@", [textField stringValue]);
    Q_EMIT mylineedit->filterChanged(QString::fromNSString([textField stringValue]));
}

@end
//----------------------------

YACReaderMacOSXToolbar::YACReaderMacOSXToolbar(QObject *parent)
    : viewSelector(0)
{
    // setup native toolbar
    nativeToolBar = nativeToolbar();
    [nativeToolBar setDisplayMode:NSToolbarDisplayModeIconOnly];
    [nativeToolBar setAllowsUserCustomization:NO];

    delegate = [[MyToolbarDelegate alloc] init];
    ((MyToolbarDelegate *)delegate)->mytoolbar = this;
    [nativeToolBar setDelegate:(MyToolbarDelegate *)delegate];

#ifdef YACREADER_LIBRARY
    NSWindow *nswindow = (NSWindow *)qApp->platformNativeInterface()->nativeResourceForWindow("nswindow", ((QMainWindow *)parent)->windowHandle());
    if ([nswindow respondsToSelector:@selector(setTitleVisibility:)]) {
        yosemite = true;
        // TODO yosemite new constants are not found in compilation time
        [nswindow setTitleVisibility:NSWindowTitleHidden];
        // TODO NSFullSizeContentViewWindowMask produces an offset in the windows' content
        // nswindow.styleMask |= 1 << 15; // NSFullSizeContentViewWindowMask;
        [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; // TODO figure out how to load specific images in Yosemite
    } else {
        [nativeToolBar setSizeMode:NSToolbarSizeModeSmall];
        yosemite = false;
    }
#else
    yosemite = false;
    [nativeToolBar setAutosavesConfiguration:YES]; // TODO this doesn't work
    [nativeToolBar setSizeMode:NSToolbarSizeModeSmall];
#endif
}

void YACReaderMacOSXToolbar::addAction(QAction *action)
{
    QMacToolBarItem *toolBarItem = addItem(action->icon(), action->text());
    if (action->data().toString() == TOGGLE_COMICS_VIEW_ACTION_YL)
        viewSelector = toolBarItem;
    connect(toolBarItem, &QMacToolBarItem::activated, action, [=] { emit action->triggered(); });

    NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem();
    actions.insert(QString::fromNSString(nativeItem.itemIdentifier), action);

    MacToolBarItemWrapper *wrapper = new MacToolBarItemWrapper(action, toolBarItem);
    // wrapper->actionToogled(true);
}

void YACReaderMacOSXToolbar::addDropDownItem(const QList<QAction *> &actions, const QAction *defaultAction)
{
    // TODO
}

void YACReaderMacOSXToolbar::addSpace(int size)
{
    QMacToolBarItem *toolBarItem = addItem(QIcon(), "");
    NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem();

    static const NSRect frameRect = { { 0.0, 0.0 }, { CGFloat(size), 16.0 } };
    NSView *view = [[NSView alloc] initWithFrame:frameRect];

    [nativeItem setView:view];
}

// reimplemented for convenience
void YACReaderMacOSXToolbar::addSeparator()
{
    // QMacToolBar::addSeparator();

    QMacToolBarItem *toolBarItem = addItem(QIcon(), "");
    NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem();

    static const NSRect frameRect = { { 0.0, 0.0 }, { 1, 16.0 } };
    CustomSeparator *view = [[CustomSeparator alloc] initWithFrame:frameRect];

    [nativeItem setView:view];
}

void YACReaderMacOSXToolbar::addStretch()
{
    QMacToolBarItem *toolBarItem = addItem(QIcon(), "");
    toolBarItem->setStandardItem(QMacToolBarItem::FlexibleSpace);
}

void YACReaderMacOSXToolbar::addWidget(QWidget *widget)
{
    // TODO fix it
    /* QMacNativeWidget *nativeWidget = new QMacNativeWidget();
    QVBoxLayout *layout = new QVBoxLayout();
    layout->addWidget(widget);
    nativeWidget->setLayout(layout);


    NSView *nativeWidgetView = reinterpret_cast<NSView *>(nativeWidget->winId());
    QMacToolBarItem *toolBarItem = addItem(QIcon(),"");
    NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem();
    [nativeItem setView:nativeWidgetView];*/
}

void YACReaderMacOSXToolbar::show()
{
    [nativeToolBar setVisible:YES];
}

void YACReaderMacOSXToolbar::hide()
{
    [nativeToolBar setVisible:NO];
}

YACReaderMacOSXSearchLineEdit *YACReaderMacOSXToolbar::addSearchEdit()
{
    QMacToolBarItem *toolBarItem = addItem(QIcon(), "");
    NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem();

    YACReaderMacOSXSearchLineEdit *searchEdit = new YACReaderMacOSXSearchLineEdit();

    if (yosemite)
        [nativeItem setView:(NSTextField *)searchEdit->getNSTextField()];
    else {
        static const NSRect searchEditFrameRect = { { 0.0, 0.0 }, { 165, 26.0 } };
        NSView *view = [[NSView alloc] initWithFrame:searchEditFrameRect];
        [view addSubview:((NSTextField *)searchEdit->getNSTextField())];
        [nativeItem setView:view];
    }

    return searchEdit;
}

// deprecated
QAction *YACReaderMacOSXToolbar::addFitToWidthSlider(QAction *attachToAction)
{
    QMacToolBarItem *toolBarItem = addItem(QIcon(":/images/viewer_toolbar/toWidthSlider.png"), "fit to width slider");

    NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem();
    actions.insert(QString::fromNSString(nativeItem.itemIdentifier), attachToAction);

    QAction *action = new QAction("", attachToAction->parent());

    connect(toolBarItem, &QMacToolBarItem::activated, action, [=] { emit action->triggered(); });

    return action;
}

void YACReaderMacOSXToolbar::updateViewSelectorIcon(const QIcon &icon)
{
    if (viewSelector)
        viewSelector->setIcon(icon);
}

void YACReaderMacOSXToolbar::attachToWindow(QMainWindow *window)
{
    QMacToolBar::attachToWindow(window->windowHandle());
}

YACReaderMacOSXSearchLineEdit::YACReaderMacOSXSearchLineEdit()
    : QObject()
{
    NSRect searchEditFrameRect = { { 0.0, -3.0 }, { 165, 32.0 } };
    // NSTextField * searchEdit = [[NSTextField alloc] initWithFrame:searchEditFrameRect];

    NSTextField *searchEdit = [[NSSearchField alloc] initWithFrame:searchEditFrameRect];
    //[searchEdit setBezelStyle:NSTextFieldRoundedBezel];

    [[searchEdit cell] setPlaceholderString:@"type to search"];

    MyTextFieldDelegate *delegate = [[MyTextFieldDelegate alloc] init];
    delegate->mylineedit = this;
    [searchEdit setDelegate:delegate];

    nstextfield = searchEdit;
}

void YACReaderMacOSXSearchLineEdit::setFocus(Qt::FocusReason reason)
{
    Q_UNUSED(reason)

    [((NSTextField *)nstextfield) becomeFirstResponder];
}

void *YACReaderMacOSXSearchLineEdit::getNSTextField()
{
    return nstextfield;
}

QString YACReaderMacOSXSearchLineEdit::text()
{
    return QString::fromNSString([((NSTextField *)nstextfield) stringValue]);
}

void YACReaderMacOSXSearchLineEdit::clear()
{
    [((NSTextField *)nstextfield) setStringValue:@""];
    emit filterChanged("");
}

void YACReaderMacOSXSearchLineEdit::clearText()
{
    // TODO be sure that this will not generate any event....
    [((NSTextField *)nstextfield) setStringValue:@""];
}

void YACReaderMacOSXSearchLineEdit::setDisabled(bool disabled)
{
    [((NSTextField *)nstextfield) setEnabled:!disabled];
}

void YACReaderMacOSXSearchLineEdit::setEnabled(bool enabled)
{
    [((NSTextField *)nstextfield) setEnabled:enabled];
}

MacToolBarItemWrapper::MacToolBarItemWrapper(QAction *action, QMacToolBarItem *toolbaritem)
    : action(action), toolbaritem(toolbaritem)
{
    if (action->isCheckable()) {
        connect(action, &QAction::toggled, this, &MacToolBarItemWrapper::actionToggled);
        connect(toolbaritem, &QMacToolBarItem::activated, action, &QAction::toggle);
        updateIcon(action->isChecked());
    }
}

void MacToolBarItemWrapper::actionToggled(bool toogled)
{
    updateIcon(toogled);
}

void MacToolBarItemWrapper::updateIcon(bool enabled)
{
    if (enabled) {
        QIcon icon = action->icon();
        QPixmap tempPixmap = icon.pixmap(QSize(24, 24));
        QPainter painter;
        painter.begin(&tempPixmap);
        painter.fillRect(QRect(3, 21, 18, 1), QColor("#3F3F3F"));
        painter.fillRect(QRect(3, 22, 18, 1), QColor("#6E6E6E"));
        painter.fillRect(QRect(3, 23, 18, 1), QColor("#EEEEEE"));
        painter.end();

        toolbaritem->setIcon(QIcon(tempPixmap));
    } else
        toolbaritem->setIcon(action->icon());
}
#else

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

NSImage *QIconToNSImage(const QIcon &icon, const QSize &size, const QColor &color = QColor())
{
    QPixmap pixmap = icon.pixmap(size);
    QImage qImage = pixmap.toImage().convertToFormat(QImage::Format_RGBA8888);

    if (color.isValid()) {
        QPainter p;

        QImage mask(qImage);

        p.begin(&mask);
        p.setCompositionMode(QPainter::CompositionMode_SourceIn);
        QBrush brush(color);
        p.fillRect(QRect(0, 0, size.width(), size.height()), brush);
        p.end();

        p.begin(&qImage);
        p.setCompositionMode(QPainter::CompositionMode_Overlay);
        p.drawImage(0, 0, mask);
        p.end();
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(
            (void *)qImage.bits(),
            qImage.width(),
            qImage.height(),
            8,
            qImage.bytesPerLine(),
            colorSpace,
            kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

    CGImageRef cgImage = CGBitmapContextCreateImage(context);
    NSImage *nsImage = [[NSImage alloc] initWithCGImage:cgImage size:NSMakeSize(qImage.width(), qImage.height())];

    // Clean up
    CGImageRelease(cgImage);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    return nsImage;
}

void bindActionToNSToolbarItem(QAction *action, NSToolbarItem *toolbarItem, const QColor &iconColor = QColor())
{
    if (action == nullptr || toolbarItem == nil) {
        return;
    }

    auto update = [=] {
        toolbarItem.enabled = action->isEnabled();

        QString text = action->text();
        QString tooltip = action->toolTip();

        toolbarItem.label = text.isEmpty() ? @"" : [NSString stringWithUTF8String:text.toUtf8().constData()];
        toolbarItem.paletteLabel = toolbarItem.label;
        toolbarItem.toolTip = tooltip.isEmpty() ? @"" : [NSString stringWithUTF8String:tooltip.toUtf8().constData()];

        QIcon icon = action->icon();

        __auto_type image = QIconToNSImage(icon, { 24, 24 }, iconColor);

        if (action->isChecked()) {
            NSSize size = image.size;
            NSImage *decoratedImage = [[NSImage alloc] initWithSize:size];

            [decoratedImage lockFocus];

            NSRect rect = NSMakeRect(0, 0, size.width, size.height);
            NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:8 yRadius:8];
            [[NSColor colorWithCalibratedRed:0.8 green:0.8 blue:0.8 alpha:0.9] setFill];
            [path fill];

            NSRect imageRect = NSMakeRect(4, 4, size.width - 8, size.height - 8);
            [image drawInRect:imageRect
                     fromRect:NSZeroRect
                    operation:NSCompositingOperationSourceOver
                     fraction:1.0];

            [decoratedImage unlockFocus];

            toolbarItem.image = decoratedImage;
        } else {
            NSSize size = image.size;
            NSImage *decoratedImage = [[NSImage alloc] initWithSize:size];

            [decoratedImage lockFocus];

            NSRect imageRect = NSMakeRect(4, 4, size.width - 8, size.height - 8);
            [image drawInRect:imageRect
                     fromRect:NSZeroRect
                    operation:NSCompositingOperationSourceOver
                     fraction:1.0];

            [decoratedImage unlockFocus];

            toolbarItem.image = decoratedImage;
        }

        [image release];
    };

    if (action->isCheckable()) {
        QObject::connect(
                action, &QAction::triggered,
                [=](bool checked) {
                    update();
                });
    }

    QObject::connect(
            action, &QAction::enabledChanged,
            [=](bool enabled) {
                toolbarItem.enabled = enabled;
            });

    QObject::connect(
            action, &QAction::changed,
            [=]() {
                update();
            });

    toolbarItem.bordered = YES;

    update();
}

#ifdef YACREADER_LIBRARY

@interface YACReaderLibraryToolbarDelegate : NSObject <NSToolbarDelegate> {
@public
    YACReaderMacOSXToolbar *mytoolbar;
}

- (IBAction)itemClicked:(id)sender;

@end

@implementation YACReaderLibraryToolbarDelegate

- (NSArray<NSToolbarItemIdentifier> *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

    return @[
        @"Back",
        @"Forward",
        @"Settings",
        @"Server",
        @"Help",
        NSToolbarSpaceItemIdentifier,
        @"ToggleView",
        NSToolbarSpaceItemIdentifier,
        @"Search",
    ];
}

- (NSArray<NSToolbarItemIdentifier> *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

    return @[
        @"Back",
        @"Forward",
        @"Settings",
        @"Server",
        @"Help",
        @"ToggleView",
        @"Search",
        NSToolbarSpaceItemIdentifier,
    ];
}

/*
- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

 NSMutableArray *array = [[NSMutableArray alloc] init];

 QList<QMacToolBarItem *> items = mytoolbar->items();
 foreach (const QMacToolBarItem * item, items) {
     [array addObject : item->nativeToolBarItem().itemIdentifier];
 }
 return array;
 //NSMutableArray *array = toolbarPrivate->getItemIdentifiers(toolbarPrivate->items, true);
 //[array addObjectsFromArray:toolbarPrivate->getItemIdentifiers(toolbarPrivate->allowedItems, true)];
 //return array;
}*/

- (IBAction)itemClicked:(id)sender
{
    NSToolbarItem *item = reinterpret_cast<NSToolbarItem *>(sender);
    QString identifier = QString::fromNSString([item itemIdentifier]);

    QAction *action = mytoolbar->actionFromIdentifier(identifier);
    ;

    if (action != nullptr) {
        action->trigger();
    }
}

- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)willBeInserted
{
    Q_UNUSED(toolbar);
    Q_UNUSED(willBeInserted);

    QString identifier = QString::fromNSString(itemIdentifier);

    if (identifier == "Search") {
        NSSearchToolbarItem *searchItem = [[NSSearchToolbarItem alloc] initWithItemIdentifier:itemIdentifier];

        searchItem.resignsFirstResponderWithCancel = true;
        searchItem.searchField.delegate = id<NSSearchFieldDelegate>(mytoolbar->getSearchEditDelegate());
        searchItem.toolTip = @"Search";

        return searchItem;
    }

    NSToolbarItem *toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];

    toolbarItem.target = self;
    toolbarItem.action = @selector(itemClicked:);

    QAction *action = mytoolbar->actionFromIdentifier(identifier);

    if (identifier == "Back") {
        toolbarItem.navigational = YES;
    } else if (identifier == "Forward") {
        toolbarItem.navigational = YES;
    }

    bindActionToNSToolbarItem(action, toolbarItem);

    return toolbarItem;
}

- (BOOL)validateToolbarItem:(NSToolbarItem *)item
{

    QString identifier = QString::fromNSString([item itemIdentifier]);

    if (identifier == "Search") {
        return YES;
    }

    QAction *action = mytoolbar->actionFromIdentifier(identifier);

    if (action == nullptr) {
        return NO;
    }

    return action->isEnabled();
}

@end

@interface YACReaderLibrarySearchDelegate : NSObject <NSSearchFieldDelegate> {
@public
    YACReaderMacOSXToolbar *mytoolbar;
}
@end

@implementation YACReaderLibrarySearchDelegate

- (void)searchFieldDidStartSearching:(NSSearchField *)sender
{
}
- (void)searchFieldDidEndSearching:(NSSearchField *)sender
{
    [sender resignFirstResponder];
}
- (void)controlTextDidChange:(NSNotification *)notification
{
    NSSearchField *searchField = notification.object;
    NSLog(@"Search text changed: %@", searchField.stringValue);

    mytoolbar->emitFilterChange(QString::fromNSString(searchField.stringValue));
}

@end

YACReaderMacOSXToolbar::YACReaderMacOSXToolbar(QWidget *parent)
    : YACReaderMainToolBar(parent)
{
    backButton->setIconSize(QSize(24, 24));
    forwardButton->setIconSize(QSize(24, 24));
    settingsButton->setIconSize(QSize(24, 24));
    serverButton->setIconSize(QSize(24, 24));
    helpButton->setIconSize(QSize(24, 24));
    toggleComicsViewButton->setIconSize(QSize(24, 24));
}

QSize YACReaderMacOSXToolbar::sizeHint() const
{
    return QSize(400, 36);
}

void YACReaderMacOSXToolbar::addAction(QAction *action)
{
    if (backButton->defaultAction() == nullptr) {
        backButton->setDefaultAction(action);
        return;
    }
    if (forwardButton->defaultAction() == nullptr) {
        forwardButton->setDefaultAction(action);
        return;
    }
    if (settingsButton->defaultAction() == nullptr) {
        settingsButton->setDefaultAction(action);
        return;
    }
    if (serverButton->defaultAction() == nullptr) {
        serverButton->setDefaultAction(action);
        return;
    }
    if (helpButton->defaultAction() == nullptr) {
        helpButton->setDefaultAction(action);
        return;
    }
    if (toggleComicsViewButton->defaultAction() == nullptr) {
        toggleComicsViewButton->setDefaultAction(action);
        return;
    }
}

void YACReaderMacOSXToolbar::addSpace(int size)
{
}

void YACReaderMacOSXToolbar::addStretch()
{
}

YACReaderMacOSXSearchLineEdit *YACReaderMacOSXToolbar::addSearchEdit()
{
    auto search = new YACReaderMacOSXSearchLineEdit();

    setSearchWidget(search);

    return search;
}

void YACReaderMacOSXToolbar::updateViewSelectorIcon(const QIcon &icon)
{
}

void YACReaderMacOSXToolbar::attachToWindow(QMainWindow *window)
{
    NSView *nsview = (NSView *)window->winId();
    NSWindow *nswindow = [nsview window];

    YACReaderLibrarySearchDelegate *searchDelegate = [[YACReaderLibrarySearchDelegate alloc] init];
    this->searchEditDelegate = searchDelegate;
    searchDelegate->mytoolbar = this;

    // Create the NSToolbar
    NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"mainToolbar"];
    [toolbar setDisplayMode:NSToolbarDisplayModeIconOnly];
    [toolbar setShowsBaselineSeparator:false];

    __auto_type delegate = [[YACReaderLibraryToolbarDelegate alloc] init];
    delegate->mytoolbar = this;
    [toolbar setDelegate:delegate];

    [nswindow setToolbar:toolbar];
}

void YACReaderMacOSXToolbar::paintEvent(QPaintEvent *)
{
}

QAction *YACReaderMacOSXToolbar::actionFromIdentifier(const QString &identifier)
{
    if (identifier == "Back") {
        return backButton->defaultAction();
    } else if (identifier == "Forward") {
        return forwardButton->defaultAction();
    } else if (identifier == "Settings") {
        return settingsButton->defaultAction();
    } else if (identifier == "Server") {
        return serverButton->defaultAction();
    } else if (identifier == "Help") {
        return helpButton->defaultAction();
    } else if (identifier == "ToggleView") {
        return toggleComicsViewButton->defaultAction();
    }

    return nullptr;
}

#else

@interface YACReaderToolbarDelegate : NSObject <NSToolbarDelegate> {
@public
    YACReaderMacOSXToolbar *mytoolbar;
}

- (IBAction)itemClicked:(id)sender;

@end

@implementation YACReaderToolbarDelegate

- (NSArray<NSToolbarItemIdentifier> *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

    auto actions = mytoolbar->actions();
    NSMutableArray<NSToolbarItemIdentifier> *identifiers = [NSMutableArray arrayWithCapacity:actions.size()];

    for (QAction *action : actions) {
        [identifiers addObject:[NSString stringWithFormat:@"action_%p", action]];
    }

    return identifiers;
}

- (NSArray<NSToolbarItemIdentifier> *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
{
    Q_UNUSED(toolbar);

    auto actions = mytoolbar->actions();
    NSMutableArray<NSToolbarItemIdentifier> *identifiers = [NSMutableArray arrayWithCapacity:actions.size()];

    for (QAction *action : actions) {
        [identifiers addObject:[NSString stringWithFormat:@"action_%p", action]];
    }

    return identifiers;
}

// - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
// {
//     Q_UNUSED(toolbar);

//     auto actions = mytoolbar->actions();
//     NSMutableArray<NSToolbarItemIdentifier> *identifiers = [NSMutableArray arrayWithCapacity:actions.size()];

//     for (QAction *action : actions) {
//         if (action->isCheckable()) {
//             [identifiers addObject:[NSString stringWithFormat:@"action_%p", action]];
//         }
//     }

//     return identifiers;
// }

- (IBAction)itemClicked:(id)sender
{
    NSToolbarItem *item = reinterpret_cast<NSToolbarItem *>(sender);
    NSString *itemIdentifier = [item itemIdentifier];

    auto actions = mytoolbar->actions();

    for (QAction *action : actions) {
        if ([itemIdentifier isEqualTo:[NSString stringWithFormat:@"action_%p", action]]) {
            action->trigger();
        }
    }
}

- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)willBeInserted
{
    Q_UNUSED(toolbar);
    Q_UNUSED(willBeInserted);

    NSToolbarItem *toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];

    toolbarItem.target = self;
    toolbarItem.action = @selector(itemClicked:);

    auto actions = mytoolbar->actions();

    for (QAction *action : actions) {
        if ([itemIdentifier isEqualTo:[NSString stringWithFormat:@"action_%p", action]]) {
            bindActionToNSToolbarItem(action, toolbarItem, QColor(200, 200, 200));
        }
    }

    return toolbarItem;
}

- (BOOL)validateToolbarItem:(NSToolbarItem *)item
{
    NSString *itemIdentifier = [item itemIdentifier];

    auto actions = mytoolbar->actions();

    for (QAction *action : actions) {
        if ([itemIdentifier isEqualTo:[NSString stringWithFormat:@"action_%p", action]]) {
            return action->isEnabled();
        }
    }

    return NO;
}

@end

YACReaderMacOSXToolbar::YACReaderMacOSXToolbar(QWidget *parent)
    : QWidget(parent)
{
    setMovable(false);
    setIconSize(QSize(24, 24));
}

void YACReaderMacOSXToolbar::attachToWindow(QMainWindow *window)
{
    NSView *nsview = (NSView *)window->winId();
    NSWindow *nswindow = [nsview window];

    NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"mainToolbar"];
    [toolbar setDisplayMode:NSToolbarDisplayModeIconOnly];
    [toolbar setShowsBaselineSeparator:false];

    __auto_type delegate = [[YACReaderToolbarDelegate alloc] init];
    delegate->mytoolbar = this;
    [toolbar setDelegate:delegate];

    [nswindow setToolbar:toolbar];
}

void YACReaderMacOSXToolbar::addStretch()
{
}

void YACReaderMacOSXToolbar::setHidden(bool hidden)
{
    NSView *nsView = reinterpret_cast<NSView *>(this->winId());
    NSWindow *window = [nsView window];
    if (window && window.toolbar) {
        window.toolbar.visible = !hidden;
    }
}
void YACReaderMacOSXToolbar::show()
{
    setHidden(false);
}

void YACReaderMacOSXToolbar::hide()
{
    setHidden(true);
}

#endif

#endif