//
//  RegistrationController.h
//  BERegistration
//
//  Created by Philipp on 20/10/2007.
//  Copyright 2007 Dare to be Creative Ltd. All rights reserved.
//

#import <Cocoa/Cocoa.h>
#import "BEDefaultRegistrationDelegate.h"
#import "BESerialNumberValidatorFactory.h"


@interface BERegistrationController : NSObject {
	NSString *licenseKey;
    NSURL *licenseFileURL;
	NSDate *expiryDate;
	NSString *productName;
	id<BERegistrationDelegate> delegate;
	NSMutableArray *validators, *upgradableValidators;
	BOOL autoLaunch;
	NSMenu *menuOfBuyAndRegisterMenuItems;
	NSInteger indexOfBuyAndRegisterMenuItems;
	NSString *upgradeMessage;
    NSString *customTrialBehaviorInformativeString;
}

#pragma mark Initialization

-(id) initWithValidator:(id<BESerialNumberValidating>) aValidator;


#pragma mark Properties

/**
 * \brief A boolean that checks whether the app is in trial mode
 * \return \p YES if in trial mode, \p NO otherwise.
 */
@property (readonly) BOOL isInTrialMode;

/**
 * \brief A boolean that checks whether the app has a custom trial behavior
 * \return \p YES if custom trial behavior is present, \p NO otherwise.
 */
@property (readonly) BOOL hasCustomTrialBehavior;

/**
 * \brief A string to show the custom trial behavior the app implements in the registration dialog
 *
 */
@property (retain) NSString *customTrialBehaviorInformativeString;

/**
 * \brief License key
 *
 * The license key is not validated and is kept in memory. To write it to persistent
 * storage (that is, register it) call registerLicenseKey().
 */
@property (retain) NSString *licenseKey;

/**
 * \brief License File URL
 *
 * The license file location set by the app, if needed.
 */
@property (retain) NSURL *licenseFileURL;

/**
 * \brief The product being registered.
 */
@property (readonly) NSString *productName;

/**
 * \brief The delegate.
 */
@property (retain) id<BERegistrationDelegate> delegate;

/**
 * \brief Whether to launch the registration check automatically after the application has launched
 */
@property (assign) BOOL autoLaunch;

/**
 * \brief When the product was first launched
 */
@property (readonly) NSDate *firstLaunchDate;

/**
 * \brief The date when the trial period expires.
 */
@property (readonly) NSDate *expiryDate;

/**
 * \brief The number of days until the trial expires.
 * \return The number of days from the current date to \ref expiryDate.
 * \see expiryDate
 */
@property (readonly) NSInteger trialDaysLeft;

/**
 * \brief Returns a Boolean value that indicates whether the trial period is over.
 * \return \p YES if the current date is after the \ref expiryDate, otherwise \p NO.
 */
@property (readonly) BOOL isTrialPeriodOver;

/**
 * \brief A Boolean value that indicates whether the license key is valid
 * \return \p YES if \ref licenseKey is valid, otherwise \p NO.
 */
@property (readonly) BOOL hasValidLicenseKey;

/**
 * \brief A Boolean value that indicates whether the license file is valid
 * \return \p YES if \ref licenseFile is valid, otherwise \p NO.
 */
@property (readonly) BOOL hasValidLicenseFile;

/**
 * \brief A Boolean value that indicates whether the registered license requires an upgrade.
 * \return \p YES if \ref licenseKey requires an upgrade, otherwise \p NO.
 */
@property (readonly) BOOL hasUpgradableLicenseKey;

/**
 * \brief  A Boolean value that indicates whether the license key can be written to persistent storage
 * \return \p YES if \ref licenseKey is either a valid or upgradable license.
 *
 * You should check this property is \p YES before calling saveLicenseKey().
 */
@property (readonly) BOOL canSaveLicenseKey;

/**
 * \brief Adds a validator for license keys.
 * \param aValidator the validator to add
 */
-(void) addValidator:(id<BESerialNumberValidating>) aValidator;

/**
 * \brief Add a validator for licenses that can be upgraded
 *
 * The upgrade dialogs will show the default upgrade message.
 */
-(void) setCanUpgradeFromValidator:(id<BESerialNumberValidating>) aValidator;

/**
 * \brief Add a validator for licenses that can be upgraded
 *
 * @param message message shown in the update dialogs regarding this upgrade
 *
 */
-(void) setCanUpgradeFromValidator:(id<BESerialNumberValidating>)aValidator message:(NSString *)message;

/**
 * \brief The message telling the user that his license key requires an upgrade
 */
@property (readonly, retain) NSString *upgradeMessage;

/**
 * \brief The menu to which the buy and register menu items are added
 *
 * Defaults to the application menu.
 */
@property (retain) NSMenu *menuOfBuyAndRegisterMenuItems;

/**
 * \brief The index at which the buy and register menu items are added
 *
 * Defaults to \p 3.
 */
@property (assign) NSInteger indexOfBuyAndRegisterMenuItems;


#pragma mark Buy and registering

-(void) addMenuItems;

/**
 * Creates a new buy menu item connected to this controller's buy action method
 */
- (NSMenuItem *) buyMenuItem;

/**
 * \brief Opens the webstore with the product in the cart
 * \see buyUpgrade:()
 */
- (IBAction) buyApplication:(id)sender;

/**
 * Creates a new register menu item connected to this controller's buy action method
 */
- (NSMenuItem *) registerMenuItem;

/**
 * \brief Brings up the registration dialog window
 */
- (IBAction) registerApplication:(id)sender;

/**
 * \brief Opens the webstore with the upgrade in the cart
 * \see buyApplication:()
 */
- (IBAction) buyUpgrade:(id)sender;

/**
 * \brief Shows the license
 */
- (IBAction) showLicense:(id)sender;


#pragma mark Operations

/**
 * \brief Launch the registration process
 */
- (void) launch;

/**
 * \brief Writes the license key to persistent storage
 */
- (void)saveLicenseKey;

/**
 * \brief Imports a license key if none exists yet from an older version identified by its bundle identifier
 */
-(void) importLicenseKeyFromBundleIfPresentAndNoLicenseKeyExists:(NSString *)bundleIdentifier;


@end
