/** 
 *  Yudit Unicode Editor Source File
 *
 *  GNU Copyright (C) 1997-2023  Gaspar Sinai <gaspar@yudit.org>  
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2,
 *  dated June 1991. See file COPYYING for details.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#import <objc/objc-runtime.h>
#import <AppKit/Appkit.h>
#import <swindow/sosx/SCocoaInput.h>

// https://en.wikibooks.org/wiki/Programming_Mac_OS_X_with_Cocoa_for_Beginners_2nd_Edition

/// https://patchwork.kernel.org/patch/9697563/

#ifndef MAC_OS_X_VERSION_10_12
#define MAC_OS_X_VERSION_10_12 101200
#endif

#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
#define NSEventMaskAny                  NSAnyEventMask
#define NSEventModifierFlagCommand      NSCommandKeyMask
#define NSEventModifierFlagControl      NSControlKeyMask
#define NSEventModifierFlagOption       NSAlternateKeyMask
#define NSEventTypeFlagsChanged         NSFlagsChanged
#define NSEventTypeKeyUp                NSKeyUp
#define NSEventTypeKeyDown              NSKeyDown
#define NSEventTypeMouseMoved           NSMouseMoved
#define NSEventTypeLeftMouseDown        NSLeftMouseDown
#define NSEventTypeRightMouseDown       NSRightMouseDown
#define NSEventTypeOtherMouseDown       NSOtherMouseDown
#define NSEventTypeLeftMouseDragged     NSLeftMouseDragged
#define NSEventTypeRightMouseDragged    NSRightMouseDragged
#define NSEventTypeOtherMouseDragged    NSOtherMouseDragged
#define NSEventTypeLeftMouseUp          NSLeftMouseUp
#define NSEventTypeRightMouseUp         NSRightMouseUp
#define NSEventTypeOtherMouseUp         NSOtherMouseUp
#define NSEventTypeScrollWheel          NSScrollWheel
#define NSTextAlignmentCenter           NSCenterTextAlignment
#define NSWindowStyleMaskBorderless     NSBorderlessWindowMask
#define NSWindowStyleMaskClosable       NSClosableWindowMask
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
#define NSWindowStyleMaskResizable      NSResizableWindowMask
#define NSWindowStyleMaskTitled         NSTitledWindowMask
#define NSWindowStyleMaskUtilityWindow  NSUtilityWindowMask

#define NSBevelLineJoinStyle NSLineJoinStyleBevel
#define NSMiterLineJoinStyle NSLineJoinStyleMiter
#define NSRoundLineJoinStyle NSLineJoinStyleRound
#define NSCompositingOperationSourceOver NSCompositeSourceOver
#endif



@interface CocoaPath  : NSObject {
    @public double strokeWidth;
}
- (id) initWithPath: (NSBezierPath*) path;
@property (nonatomic, retain) NSBezierPath* path;
@property (nonatomic, retain) NSColor* fillColor;
@property (nonatomic, retain) NSColor* strokeColor;
@end

// https://www.develop-bugs.com/article/25480493/Subclassing+NSWindow+hover+resize

// NSApplicationDelegate is a protocol
@interface CocoaWindowDelegate : NSWindowController <NSWindowDelegate>
- (void) windowDidResize: (NSNotification*) notification;
- (void) windowDidBecomeKey: (NSNotification*) notification;
- (void) windowDidResignKey: (NSNotification*) notification;
@end

@interface CocoaWindow : NSWindow {
}
@property (nonatomic, assign) void* currentModal;
@property (nonatomic, assign) NSView* lastFocusView;
// we need this because contentView gets repalaced with a view in between by addContentView.
@property (nonatomic, assign) NSView* topLevelCocoaView;
@end

@interface CocoaImage : NSImage 
   @property (nonatomic, assign) NSPoint translate;
@end

#if __cplusplus
#include "swindow/sosx/SOSX.h"
#include "swindow/sosx/SEventOSX.h"
#endif /*__cplusplus */

@interface CocoaAccelerator   : NSObject
- (id) init:(int)key ctrl:(bool)ctrl shift:(bool)shift meta:(bool)meta listener:(SAcceleratorListener*)listener;
- (BOOL) fireKeyPressed:(int)key ctrl:(bool)ctrl shift:(bool)shift meta:(bool)meta;
- (BOOL) fireKeyReleased;
- (BOOL) matches: (CocoaAccelerator*) accelerator;
- (BOOL) isPressed; 
@end

@interface CocoaView : CocoaInput {
    @public bool cocoaHasMinimumSize;
    @public NSSize cocoaMinimumSize;
    @public double currentScroll;
}
@property (nonatomic, assign) CocoaPath* currentPath;
@property (nonatomic, assign) NSMutableArray<CocoaPath*>* currentImage;
@property (nonatomic, retain) NSString* viewName;
// Moved to CocoaInput
//@property (nonatomic, assign) SOSXWindow* cppWindow;
@property (nonatomic, retain) CocoaWindow* nsWindow;
//@property (nonatomic, assign) NSView* backView;
@property (nonatomic, assign) NSRect clipRect;
@property (nonatomic, assign) NSGraphicsContext* graphicsContext;
@property (nonatomic, assign) CocoaView* modalParent;
@property (nonatomic, assign) bool decorated;
@property (nonatomic, assign) NSTrackingRectTag trackingRect;
@property (nonatomic, assign) BOOL trackingIN;
@property (nonatomic, assign) CocoaView* pendingFocusView;
@property (nonatomic, assign) BOOL droppable;
@property (nonatomic, retain) NSMutableArray<CocoaAccelerator*>* accelerators;

- (id)initWithFrame:(NSRect)frameRect;
- (void)cocoaShow;
- (void)cocoaHide;
- (BOOL)cocoaIsTopLevel;
- (BOOL)cocoaEventOK;
- (void) setTrackingArea;
- (void) clearTrackingArea;
- (BOOL) gainKeyboardFocus;
- (void) registerDroppable;
- (void) cocoaKeyDown: (NSEvent *) event;
- (void) cocoaKeyUp: (NSEvent *) event;
- (CocoaView*) getLastFocusView;
- (CocoaView*) getTopLevelView;
- (void) cocoaAddAccelerator:(CocoaAccelerator*)accelerator;
- (void) cocoaRemoveAccelerator:(CocoaAccelerator*)accelerator;
- (void) buildChildAccelerators: (NSMutableArray<CocoaAccelerator*>*) array; 
- (void) cocoaMakeFirstResponder;
@end

// NSApplicationDelegate is a protocol
@interface CocoaApplicationDelegate : NSObject <NSApplicationDelegate>
- (void) applicationWillFinishLaunching: (NSNotification *)notification;
- (void) applicationDidFinishLaunching: (NSNotification *)notification;
@end

@interface CocoaTimer : NSObject 
-(id) initWithRepeating:(SEventOSX*)eventHandler client:(SClientOSX*)client timeout:(float)timeout;
-(void) handleTimeout;
-(void) invalidate;

@property (nonatomic, assign) NSTimer* delegate;
@property (nonatomic, assign) SEventOSX* eventHandler;
@property (nonatomic, assign) SClientOSX* client;

@end
