//
//	GSTabBarControl.h
//	GSTabBarControl
//
//	Created by John Pannell on 10/13/05.
//	Copyright 2005 Positive Spin Media. All rights reserved.
//

/*
   This view provides a control interface to manage a regular NSTabView.	It looks and works like the tabbed browsing interface of many popular browsers.
 */

#import <Cocoa/Cocoa.h>
@class GSTabBarControl;

@protocol TabBarControlDelegate

//Standard NSTabView methods
- (BOOL)tabBar:(GSTabBarControl *)tabBarControl willUnselectTabItem:(NSViewController *)tabItem;
- (void)tabBar:(GSTabBarControl *)tabBarControl didSelectTabItem:(NSViewController *)tabItem;
- (BOOL)tabBar:(GSTabBarControl *)tabBarControl shouldCloseTabItem:(NSViewController *)tabItem;
- (void)tabBar:(GSTabBarControl *)tabBarControl didCloseTabItem:(NSViewController *)tabItem;
@optional
//"Spring-loaded" tabs methods
- (NSArray *)allowedDraggedTypesForContentView:(NSView *)aContentView;
- (void)tabBar:(GSTabBarControl *)tabBarControl acceptedDraggingInfo:(id <NSDraggingInfo> ) draggingInfo onTabItem:(NSViewController *)tabItem;

//Contextual menu method
- (NSMenu *)tabView:(NSView *)aContentView menuForTabItem:(NSViewController *)tabItem;

//Drag and drop methods
- (BOOL)shouldDragTabItem:(NSViewController *)tabItem fromTabBar:(GSTabBarControl *)tabBarControl;
- (BOOL)shouldDropTabItem:(NSViewController *)tabItem inTabBar:(GSTabBarControl *)tabBarControl;
- (BOOL)shouldAllowTabItem:(NSViewController *)tabItem toLeaveTabBar:(GSTabBarControl *)tabBarControl;
- (void)didDropTabItem:(NSViewController *)tabItem inTabBar:(GSTabBarControl *)tabBarControl;


//Tear-off tabs methods
- (NSImage *)tabBar:(GSTabBarControl *)tabBarControl imageForTabItem:(NSViewController *)tabItem offset:(NSSize *)offset styleMask:(NSUInteger *)styleMask;
- (GSTabBarControl *)tabBar:(GSTabBarControl *)tabBarControl newTabBarForDraggedTabItem:(NSViewController *)tabItem atPoint:(NSPoint)point;
- (void)tabBar:(GSTabBarControl *)tabBarControl closeWindowForLastTabItem:(NSViewController *)tabItem;

//Overflow menu validation
- (BOOL)tabBar:(GSTabBarControl *)tabBarControl validateOverflowMenuItem:(NSMenuItem *)menuItem forTabItem:(NSViewController *)tabItem;
- (void)tabBar:(GSTabBarControl *)tabBarControl tabItem:(NSViewController *)tabItem isInOverflowMenu:(BOOL)inOverflowMenu;

//tab bar hiding methods
- (void)tabBarDidHide:(GSTabBarControl *)tabBarControl;
- (void)tabBarDidUnhide:(GSTabBarControl *)tabBarControl;
- (CGFloat)desiredWidthForVerticalTabBar:(GSTabBarControl *)tabBarControl;

//closing
- (void)tabBar:(GSTabBarControl *)aTabBar willCloseTabItem:(NSViewController *)tabItem;
- (BOOL)tabBar:(GSTabBarControl *)tabBarControl disableTabCloseForTabItem:(NSViewController *)tabItem;

//tooltips
- (NSString *)tabBar:(GSTabBarControl *)tabBarControl toolTipForTabItem:(NSViewController *)tabItem;

//accessibility
- (NSString *)accessibilityStringForTabBar:(GSTabBarControl *)tabBarControl objectCount:(NSInteger)objectCount;

@end

#define PSMTabDragDidEndNotification @ "PSMTabDragDidEndNotification"
#define PSMTabDragDidBeginNotification @ "PSMTabDragDidBeginNotification"

// internal cell border
#define MARGIN_X		14
#define MARGIN_Y		2
// padding between objects
#define kPSMTabBarCellPadding 8
// fixed size objects
#define kPSMMinimumTitleWidth 30

#define kPSMHideAnimationSteps 3.0

// Value used in _currentStep to indicate that resizing operation is not in progress
#define kPSMIsNotBeingResized -1

// Value used in _currentStep when a resizing operation has just been started
#define kPSMStartResizeAnimation 0

#define MAX_OVERFLOW_MENUITEM_TITLE_LENGTH	60


@class PSMOverflowPopUpButton, PSMRolloverButton, PSMTabBarCell;//, GSTabBarController;
@protocol PSMTabStyle;

typedef enum {
	PSMTabBarHorizontalOrientation,
	PSMTabBarVerticalOrientation
} PSMTabBarOrientation;

typedef enum {
	PSMTabBarTearOffAlphaWindow,
	PSMTabBarTearOffMiniwindow
} PSMTabBarTearOffStyle;

enum {
	PSMTab_SelectedMask				= 1 << 1,
		PSMTab_LeftIsSelectedMask		= 1 << 2,
		PSMTab_RightIsSelectedMask		= 1 << 3,
		PSMTab_PositionLeftMask			= 1 << 4,
		PSMTab_PositionMiddleMask		= 1 << 5,
		PSMTab_PositionRightMask		= 1 << 6,
		PSMTab_PositionSingleMask		= 1 << 7
};

@interface GSTabBarControl : NSControl <NSAnimationDelegate, NSMenuDelegate> {
	//id							observedObjectForSelectionIndex;
	//NSString					*observedKeyPathForSelectionIndex;
	//id							observedObjectForContentArray;
	//NSString					*observedKeyPathForContentArray;

	NSMutableArray *_viewControllers;
	NSUInteger _selectionIndex;
	NSViewController *__unsafe_unretained _currentItem;
	// control basics
	NSMutableArray *_cells;									// the cells that draw the tabs
	NSView *__unsafe_unretained _contentView;									// the view being navigated
	PSMOverflowPopUpButton *_overflowPopUpButton;			// for too many tabs
	PSMRolloverButton *_addTabButton;
	//GSTabBarController			*_controller;

	// Spring-loading.
	NSTimer	*_springTimer;
	//NSTabViewItem				*_tabItemWithSpring;

	// drawing style
	id <PSMTabStyle> style;
	BOOL _canCloseOnlyTab;
	BOOL _disableTabClose;
	BOOL _hideForSingleTab;
	BOOL _showAddTabButton;
	BOOL _sizeCellsToFit;
	BOOL _useFullWidth;
	BOOL _useOverflowMenu;
	BOOL _alwaysShowActiveTab;
	BOOL _allowsScrubbing;
	NSInteger _resizeAreaCompensation;
	PSMTabBarOrientation _orientation;
	BOOL _automaticallyAnimates;
	NSTimer	*_animationTimer;
	PSMTabBarTearOffStyle _tearOffStyle;

	// behavior
	BOOL _allowsBackgroundTabClosing;
	BOOL _selectsTabsOnMouseDown;

	// vertical tab resizing
	BOOL _allowsResizing;
	BOOL _resizing;

	// cell width
	NSInteger _cellMinWidth;
	NSInteger _cellMaxWidth;
	NSInteger _cellOptimumWidth;

	// animation for hide/show
//	NSInteger					_currentStep;
	BOOL _isHidden;
	id _partnerView;										// gets resized when hide/show
	BOOL _awakenedFromNib;
	NSInteger _tabBarWidth;
//	NSTimer						*_showHideAnimationTimer;

	// drag and drop
	NSEvent	*_lastMouseDownEvent;							// keep this for dragging reference
	BOOL _didDrag;
	BOOL _closeClicked;

	// MVC help
	NSObject <TabBarControlDelegate> *__weak _delegate;

	NSMutableArray *_cellTrackingRects, *_closeButtonTrackingRects;
	NSMutableArray *_cellFrames;
	NSRect _addButtonRect;
	NSMenu *_overflowMenu;
	//NSViewAnimation *_animator;
}
@property (nonatomic, unsafe_unretained) IBOutlet NSView *contentView;
@property (nonatomic, strong) NSMutableArray *viewControllers;
@property (nonatomic, readonly) NSUInteger selectionIndex;
@property (nonatomic, readonly) NSUInteger numberOfTabItems;
@property (nonatomic, strong) NSMutableArray *cells;
@property (nonatomic, strong) IBOutlet id partnerView;
@property (nonatomic, readonly) PSMOverflowPopUpButton *overflowPopUpButton;
@property (nonatomic, strong) PSMRolloverButton	*addTabButton;
//@property (retain) GSTabBarController			*controller;
@property (nonatomic, strong) NSTimer *springTimer;
//@property (nonatomic, strong) NSTabViewItem				*tabItemWithSpring;
@property (nonatomic, strong) id <PSMTabStyle> style;
@property (nonatomic) PSMTabBarOrientation orientation;
@property (nonatomic) BOOL canCloseOnlyTab;
@property (nonatomic) BOOL disableTabClose;
@property (nonatomic) BOOL hideForSingleTab;
@property (nonatomic) BOOL showAddTabButton;
@property (nonatomic) BOOL sizeCellsToFit;
@property (nonatomic) BOOL useFullWidth;
@property (nonatomic) BOOL useOverflowMenu;
@property (nonatomic) BOOL alwaysShowActiveTab;
@property (nonatomic) BOOL allowsScrubbing;
@property (nonatomic) NSInteger	resizeAreaCompensation;
@property (nonatomic) BOOL automaticallyAnimates;
@property (nonatomic, strong) NSTimer *animationTimer;
@property (nonatomic) BOOL allowsBackgroundTabClosing;
@property (nonatomic) BOOL selectsTabsOnMouseDown;
@property (nonatomic) BOOL allowsResizing;
@property (nonatomic) BOOL resizing;
@property (nonatomic) NSInteger	cellMinWidth;
@property (nonatomic) NSInteger	cellMaxWidth;
@property (nonatomic) NSInteger	cellOptimumWidth;
//@property NSInteger								currentStep;
@property (nonatomic, getter = isTabBarHidden) BOOL	isHidden;
@property (nonatomic) BOOL awakenedFromNib;
@property (nonatomic) NSInteger	tabBarWidth;
//@property (retain) NSTimer						*showHideAnimationTimer;
@property (nonatomic, strong) NSEvent *lastMouseDownEvent;
@property (nonatomic) BOOL didDrag;
@property (nonatomic) BOOL closeClicked;
@property (nonatomic) PSMTabBarTearOffStyle	tearOffStyle;
@property (nonatomic, weak) id delegate;
@property (nonatomic, unsafe_unretained, setter = selectTabItem :) NSViewController	*selectedTabItem;

@property (nonatomic, strong) NSMutableArray *cellFrames;
@property (nonatomic, strong) NSMenu *overflowMenu;

// control characteristics
+ (NSBundle *)bundle;
- (CGFloat)availableCellWidth;
- (NSRect)genericCellRect;

- (NSString *)styleName;
- (void)setStyleNamed:(NSString *)name;

- (void)tabClick:(id)sender;
- (void)addTabItem:(NSViewController *)item;
- (void)insertTabItem:(NSViewController *)Item atIndex:(NSUInteger)Index;
- (void)removeTabItem:(NSViewController *)Item;
- (void)closeTabItem:(NSViewController *)item;
- (NSViewController *)tabItemAtIndex:(NSInteger)Index;
- (NSUInteger)indexOfCell:(id)Cell;
- (NSInteger)numberOfVisibleTabs;
- (PSMTabBarCell *)lastVisibleTab;
- (void)update;
// special effects
- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate;
//- (BOOL)isTabBarHidden;
- (BOOL)isAnimating;

// internal bindings methods also used by the tab drag assistant
- (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabItem:(NSViewController *)Item;
- (void)_removeCell:(PSMTabBarCell *)cell;

// aus Controller
//- (NSRect)addButtonRect;
//- (NSMenu*)overflowMenu;
- (NSRect)cellTrackingRectAtIndex:(NSInteger)index;
- (NSRect)closeButtonTrackingRectAtIndex:(NSInteger)index;
- (NSRect)cellFrameAtIndex:(NSInteger)index;

- (void)selectTabItemAtIndex:(NSUInteger)Index;
- (void)_setSelectedCell:(PSMTabBarCell *)cell;

- (void)layoutCells;
@end
