/*

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

 Abstract: Object describing a license key. Handles decryption of license key and gives access to its attributes.

 Related: <#related#>

 Documentation: <#link to documentation#>

 */



#pragma mark
#pragma mark Debug

// define DEBUG_BXLICENSEKEY for debugging this file
// #define DEBUG_BXLICENSEKEY

#pragma mark
#pragma mark Filestrings

// define file strings
#define FILE_SUFIX @"BX"
#define FILE_EXTENSION @"license"

#pragma mark
#pragma mark Key-levels

// define key levels
#define LITE @"1"
#define DV @"2"
#define PRO @"3"
#define PROSUMER @"4"
#define HR @"5"
#define SPEZIAL @"6"
#define EXPRESS @"7"
#define HOME @"8"

#pragma mark
#pragma mark Key-types

// define key types
#define DEMO @"D"
#define NFR @"N"
#define PROMO @"P"
#define FAMILY @"F"
#define EDUCATION @"E"
#define SEEDING @"S"

#pragma mark
#pragma mark Key-fields

// define key fields
#define APPNAME @"Product"
#define USERNAME @"Name"
#define ORGANISATION @"Organisation"
#define KEY @"Key"
#define EXPIRATION_NOTE @"Notified"
#define INSTALL_DATE @"Install Date"
#define VERSIONNUMBER @"Version-Number"
#define UPDATED_DATE @"Updated on"
#define APPSTORE_RECEIPT @"AppStore Receipt" // If empty this is no AppStore based license

#pragma mark
#pragma mark Key-results

//define key results
//#define APP_NAME @"A"
#define APP_KEY @"P"
#define APP_VERSION @"V"
#define USER_NAME @"U"
#define USER_ORGANISATION @"F"
#define KEY_LEVEL @"O"
#define KEY_TYPE @"T"
#define KEY_DEMO_OPTIONS @"D"
#define KEY_MODULES @"M"
#define KEY_EXPIRE_DATE @"E"
#define CUSTOMER_NUMBER @"C"
#define LICENSED_SEATS @"L"
#define FILE_PATH @"W"

#pragma mark

@interface NSMutableAttributedString (RedHighlighting)
- (void)appendString:(NSString *)otherString highlight:(BOOL)highlight;
@end

#ifdef BX_BUILD_STYLE_RELEASE

	#define initWithDictionaryFromDongle initWithSearchResultDict

	#define stolenKey binarySearch
	#define knownKey treeSearch
	#define betaKey ultraSearch
	#define checkLicenseKey searchForIndex

	#define saveLicenseKeyAtPath loadFromPath
	#define loadLicenseKeyAtPath saveToPath

	#define licenseDict enviroment
	#define licenseKeyDict isConfigured
	#define licenseResultDict configuration
	#define licenseProductName configurations
	#define	canonicalLicenseProductName configurationsWithDuplicates

	#define isBoxLicense isAdjusted
	#define isUnpersonalLicense isFixed
	#define isDemo isPlaying
	#define isNFR hasSubEntries
	#define isExpired subentries
	#define isTimeLimited limitations
	#define isStolen isLimited
	#define isBlacklisted names
	#define isBetalicense nameEnum
	#define isDongleLicense isDoubleBuffered
#endif

@interface BXLicenseKey : NSObject {
    NSMutableDictionary *licenseDict;
    NSMutableDictionary *licenseResultDict;

    NSString *oldFilename;
    
	NSDictionary *humanReadableProgrammNames;
	
    BOOL readable;
    BOOL personalized;
	BOOL useOldFilename;
	BOOL _internalExchange;
	BOOL _isDongleLicense;
}

// this method has been replaced by -[NSMutableAttributedString appendString:highlight:]
+ (NSMutableAttributedString *) string:(NSMutableAttributedString *)theString stringByAppendingString:(NSString *)aString highlight:(BOOL)highlight;
+ (NSDictionary *) loadHumanReadableProductNames;

- (id)initWithDictionary:(NSDictionary*)dictionary internalExchange:(BOOL)inInternalExchange;
- (id) initWithDictionary:(NSDictionary *)dictionary;
- (id) initWithDictionaryFromDongle:(NSDictionary *)dictionary;
- (id) initWithKey:(NSString *)key name:(NSString *)name organisation:(NSString *)organisation;
- (id)initWithKey:(NSString*)key name:(NSString*)name organisation:(NSString*)organisation internalExchange:(BOOL)inInternalExchange;
- (id) initWithFile:(NSString *)path;

- (BOOL) saveLicenseKeyAtPath:(NSString *)path;
- (BOOL) loadLicenseKeyAtPath:(NSString *)path;
- (BOOL) removeFromFilesystem;

- (NSString *) stringValue;
- (NSAttributedString *) attributedStringValue;
- (NSAttributedString *) resultStringWithKeys:(NSString*)format makeLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;

- (NSAttributedString *)resultStringForUsernameWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForProductWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForVersionWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForCustomerNumberWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForKeyTypeWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForOptionsWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForKeyLevelWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForSeatsWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
//- (NSAttributedString *)resultStringForLocationWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForExpirationDateWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;

- (NSDictionary *) licenseDict;
- (NSDictionary *) licenseKeyDict;
- (NSDictionary *) licenseResultDict;
- (NSString *)licenseProductName;
+ (NSDictionary *)loadCanonicalProductNames;
- (NSString *)canonicalLicenseProductName;

- (void) setKey:(NSString *)key name:(NSString *)name organisiation:(NSString *)organisation;
- (BOOL) expirationNoteHasBeenDisplayed;
- (void) setExpirationNoteHasBeenDisplayed:(BOOL)value;


- (BOOL) isBoxLicense;
- (BOOL) isUnpersonalLicense;
- (BOOL) isJapaneseLicense;
- (BOOL) isDemo;
- (NSString *) demoOptions;
- (BOOL) isNFR;
- (BOOL) isExpired;
- (BOOL) isTimeLimited;
- (BOOL) isStolen;
- (BOOL) isBlacklisted;
- (BOOL) isBetalicense;
- (BOOL) isDongleLicense;
- (BOOL) isUpdated;
- (BOOL)isInternalExchange;
- (NSString *)internalExchangeString;
- (BOOL)isAppStoreLicense;

+ (NSString *) shiftString:(NSString *)input withValue:(int)shift;
- (NSString *) shiftString:(NSString *)input withValue:(int)shift;
- (BOOL) checkLicenseKey;
- (BOOL) stolenKey;
- (BOOL) knownKey;
- (BOOL) betaKey;
- (BOOL) knownNameOrg;
- (NSCalendarDate *) convertInternalDate:(NSString *)date;

- (BOOL) hasBetterDemoOptionsAsLicense:(BXLicenseKey *)newLicenseKey;
- (BOOL) hasBetterOptionsAsLicense:(BXLicenseKey *)newLicenseKey;


//The following methods should be private...

//Accessor methods
- (NSString *)oldFilename;
- (void)setOldFilename:(NSString *)value;
- (NSDictionary *)humanReadableProgrammNames;
- (void)setHumanReadableProgrammNames:(NSDictionary *)dict;
- (BOOL)useOldFilename;
- (void)setUseOldFilename:(BOOL)value;
- (void)setFilePath:(NSString *)path;

- (NSDate *)updatedOn;
- (void)setUpdatedOn:(NSDate *)inDate;
@end

