/*

 Owner: Michael Ehrmann <michael@boinx.com>
 Company: Boinx Software Ltd., Germany
 Projects: BXQuartzComposer

 Abstract: Controls loading and saving of licenses, as well as choosing the right one.

 */



#if defined(MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
#define kBonjourCheck 0
#else
#define kBonjourCheck 0 // must be always 0 here, bonjour checking not supportet on 10.4
#endif


#define kLicenseStatusNone 0
#define kLicenseStatusFull 1
#define kLicenseStatusDemo 2

#define kNoLicensePanelDesignOld 1
#define kNoLicensePanelDesignNew 2
#define kNoLicensePanelDesignSmall 3

#define kApplicationFreeLicenseType 1
#define kApplicationCostLicenseType 2

#define kFullLicensesCategoryKey @"FullLicenses"
#define kDemoLicensesCategoryKey @"DemoLicenses"


//enum {
//	BXNoLicensePanelDesignOld = 1,
//	BXNoLicensePanelDesignNew = 2
//} BXNoLicensePanelDesign;
//
//enum {
//	BXFreeLicense = 1,
//	BXCostLicense = 2
//} BXApplicationLicenseType;
//
#pragma mark

@class BXLicenseKey, BXLicenseKeyChecker;

extern NSString* const BXLicenseListDidChangeNotification;

@interface BXLicenseController : NSObject <NSTableViewDataSource>
{
	id noLicensePanelController;
	
	IBOutlet NSWindow *stolenLicenseMessageWindow;
	IBOutlet NSTextField *stolenLicenseTitle;
	IBOutlet NSTextField *stolenLicenseMessage;
	IBOutlet NSTextField *stolenLicense;
	IBOutlet NSTextField *ourPassion;
	IBOutlet NSTextField *boxHeaderText;
	IBOutlet NSButton *uninstallButton;
	IBOutlet NSButton *quitButton;
	
    NSMutableArray *licenseList;
	NSMutableArray *modifiedLicenseList;
	NSMutableArray *_invalidLicenses;
	NSDictionary *_licenseCategories;
    BXLicenseKey *usedLicenseKey;
	
    NSString *defaultApp;
    NSString *defaultVersion;
	
	NSString *filenameFilter;
	BOOL onlyAddLicensesForDefaultApp;
	
	BOOL suppressDemoLicenseMessage;
	
	BXLicenseKeyChecker *_currentChecker;
	
	@private
		BOOL _useHASPDongle;
}

#pragma mark

// returns the default licencecontroller (USE ONLY THIS METHOD TO ACCESS THE CONTROLLER!)
+ (id) defaultLicenseController;

// override to return application specific license key
+ (Class) entryClass;

+ (Class) noLicensePanelControllerClass;
- (NSString *)classBundleIdentifier;

+ (BOOL)isString:(NSString*)string inArray:(NSArray*)array;

- (id) initWithAppKey:(NSString *)inAppKey appVersion:(NSString *)inAppVersion allowsDongle:(BOOL)inAllowsDongle;

- (void) openURLbyKey:(NSString*)theURLKey;

// returns the licensearray
- (NSArray*)licenses;
// returns the licensearray without AppStore Licenses
- (NSArray*)visibleLicenses;
// Stringarray  returns the appkeys for accepted licenses
- (NSArray*)acceptedLicenseKeys;
// just number of licenses > 0
- (BOOL)hasLicense;
// the counter of the licensearray
- (unsigned int)numberOfLicenses;
- (NSAttributedString*) attributedStringValue;
// accessors to modifiedLicenseList
- (NSMutableArray *)modifiedLicenseList;
- (void)setModifiedLicenseList:(NSMutableArray *)inModifiedLicenseList;

/*
 add and remove license to the licenselist
 */

- (void)addLicense:(BXLicenseKey*)theLicense;
- (void)addLicense:(BXLicenseKey*)theLicense showMessage:(BOOL)showMessage;
- (void)addLicense:(BXLicenseKey*)theLicense showMessage:(BOOL)showMessage saveLicense:(BOOL)inSaveLicense;

- (void)addLicenses:(NSArray*)theLicenses;
- (void)addLicenses:(NSArray*)theLicenses showMessage:(BOOL)showMessage;
- (void)addLicenses:(NSArray*)theLicenses showMessage:(BOOL)showMessage saveLicenses:(BOOL)inSaveLicenses;

- (void)removeLicense:(BXLicenseKey*)theLicense;

- (void)updateLicense:(BXLicenseKey *)inLicense onDate:(NSDate *)inDate;

- (BXLicenseKey *) bestLicenseKey;
- (BXLicenseKey *) bestLicenseKeyWithMessage:(BOOL)inMessage;
- (void) findBestLicenseKey;
- (int)showWarningMessageForDemoKey:(BXLicenseKey *)maxDemo andFullKey:(BXLicenseKey *)maxFull;

- (void)setSuppressDemoLicenseMessage:(BOOL)inSuppressDemoLicenseMessage;
- (BOOL)suppressDemoLicenseMessage;

- (void) postLicenseListDidChangeNotification;

- (BOOL) openAppStoreLicenseInstallPanel;
- (BOOL) showAppStoreChooser;

- (IBAction)checkForNonValidKeyLevel:(id)sender;
- (BOOL) isAppStore;
- (BOOL) isBetaVersion;
- (BOOL) usesAssistant;
- (BOOL) useHASPDongle;
- (BOOL) needsToRegister;
- (BOOL) loadStolenLicense;
- (BOOL) loadBundleLicenses;
- (BOOL) hasOlderVersions;

- (void)insertObject:(BXLicenseKey *)inLicense inLicenseListAtIndex:(unsigned int)index;
- (void)removeObjectFromLicenseListAtIndex:(unsigned int)index;


- (NSArray *)getLicenseInfoFromPasteboard;
- (NSArray *)parsePasteboardString:(NSString *)inString;
- (void)parseLicenseURLParameter:(NSDictionary *)query;

/*
 Save, load lists of licenses
 */

- (BOOL)saveLicenses;
- (BOOL)loadLicenses;
- (BOOL) loadLicensesFormBundleWithIdentifier:(NSString *)inBundleIdentifier;

// just a helper for saveLicense and loadLicense
- (NSArray*)readableLicensePathsForDomain:(NSSearchPathDomainMask)mask;
- (NSArray*)writeableLicensePathsForDomain:(NSSearchPathDomainMask)mask;


/*
 Find methods
 */

- (BXLicenseKey*)licenseForKey: (NSString*)key;
- (BXLicenseKey*)licenseForApplication: (NSString*)app version:(NSString*)version options:(NSString*)options;
- (NSArray*) licensesForApplication:(NSString*)app version:(NSString*)version option:(NSString*)option;
- (NSArray *)licensesForDefaultApplicationOfType:(NSString *)inType;
- (NSArray *)licensesForApplication:(NSString *)inApp ofType:(NSString *)inType;
- (NSArray *)licensesForApplication:(NSString *)inApp version:(NSString *)inVersion ofType:(NSString *)inType;

- (NSArray*) allValidLicensesForDefaultAppAndVersion;
- (NSArray*)allLicensesForDefaultApplication;
- (NSArray*)allLicensesForApplication:(NSString*)app;

- (BXLicenseKey*)maxDemoLicenseForDefaultApplication;
- (BXLicenseKey*)maxPurchasedLicenseForDefaultApplication;
- (BXLicenseKey*)maxLicenseForApplication:(NSString*)app returnsDemo:(BOOL)returnsDemo;
- (BXLicenseKey*)maxLicenseForApplication:(NSString*)app version:(NSString *)inVersion returnsDemo:(BOOL)returnsDemo;
- (BXLicenseKey *)bestLicenseKeyForApplicationIncludingOldVersions:(NSString*)inApp returnsDemo:(BOOL)inReturnsDemo;

/*
 Methods for licensecontrolling
 */
    //Uses defaultApp, defaultVersion and all options
- (BOOL)isLicensed;
    //Uses defaultVersion and all options
- (BOOL)isLicensedForApp:(NSString*)app;
    //Uses defaultApp and all options
- (BOOL)isLicensedForVersion:(NSString*)ver;
    //Uses defaultApp and defaultVersion
- (BOOL)isLicensedForOption:(NSString*)opt;
    //Uses all options
- (BOOL)isLicensedForApp:(NSString*)app version:(NSString*)ver;
    //Uses all arguments
- (BOOL)isLicensedForApp:(NSString*)app version:(NSString*)ver options:(NSString*)opt;

//Uses [self defaultApp],[self defaultVersion] and all options
- (int)licenseStatus;
//Uses [self defaultApp] and [self defaultVersion]
- (int)licenseStatusForOption:(NSString*)opt;

- (int)licenseStatusForApplication:(NSString *)inApp version:(NSString *)inVersion option:(NSString *)inOption;

- (BOOL) isSufficientLicense:(BXLicenseKey *)inKey
				   forOption:(NSString *)inOption; 


- (BOOL) isSufficientLicense:(BXLicenseKey *)inKey
				   forOption:(NSString *)inOption 
				 application:(NSString *)inApplication 
					 version:(NSString *)inVersion;

- (void)categorizeLicenses;

- (NSString *)canonicalDefaultAppName;

#pragma mark Seeding
+ (BOOL)isSeeding;
- (BOOL)isSeeding;
- (BOOL)isSeedingLicense:(BXLicenseKey *)inLicenseKey;

#pragma mark
#pragma mark Accessormethods
#pragma mark

- (NSString*)defaultApp;
- (void)setDefaultApp:(NSString*)value;

- (NSString*)defaultVersion;
- (void)setDefaultVersion:(NSString*)value;

- (BXLicenseKey *)usedLicenseKey;
- (void)setUsedLicenseKey:(BXLicenseKey *)inUsedLicenseKey;

- (NSString*)filenameFilter;
- (void)setFilenameFilter:(NSString*)value;

- (BOOL)onlyAddLicensesForDefaultApp;
- (void)setOnlyAddLicensesForDefaultApp:(BOOL)value;

- (id)noLicensePanelController;
- (void)setNoLicensePanelController:(id)newNoLicensePanelController;
- (IBAction) buyLicense:(id)sender;

- (NSMutableArray *)invalidLicenses;
- (void)insertObject:(BXLicenseKey *)inLicense inInvalidLicensesAtIndex:(unsigned int)index;
- (void)removeObjectFromInvalidLicensesAtIndex:(unsigned int)index;



#pragma mark
#pragma mark Stolen License Handling
#pragma mark

- (BOOL)handleStolenLicense:(BXLicenseKey *)inLicense;
- (IBAction)defaultButton:(id)sender;
- (IBAction)alternateButton:(id)sender;


#pragma mark -
#pragma mark Bonjour Checking

- (IBAction)announceLicense:(id)sender;
- (void)stopCurrentService;


#pragma mark -
#pragma mark AppStore to BXLicense Conversion
// Override this Method to generate a B License to convert AppStore License
// Don't override or return nil for AppStore Identifiers that aren't supported
// named like this in order to be obfuscated
- (BXLicenseKey *)BXLicenseKeyForAppStoreIdentifier:(NSString *)inAppStoreIdentifier dictionary:(NSDictionary *)inDictionary receipt:(NSData *)inReceipt;

@end

#pragma mark
@protocol BXLicensedClass 
#pragma mark

//- (id)registerClass;
- (NSArray*) selectorsForOption:(NSString*)option;
//- (BOOL)needsLicenseWithName:(NSString*)name version:(NSString*)version options:(NSString*)level;

@end

@interface NSObject (HideBuyOption)

- (BOOL)shouldHideBuyOption;

@end

#pragma mark Utilities from Sparkle

#if defined(__cplusplus)	
extern "C" {
#endif

NSComparisonResult SUStandardVersionComparison(NSString * versionA, NSString * versionB);

#if defined(__cplusplus)	
}
#endif
