//
//  BISubstrateDefines.h
//  BISubstrate
//
//  Created by Eric Hochmeister on 18/01/05.
//  Copyright 2005 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>


/*
 
 BIIdleThresholdInMinutes - the amount of time the user has to be away for in order for us to consider them idle
 BIIdleTimersAction - 1 -> Warn me when I have been idle
                      2 -> Automatically pause when I go idle
                      3 -> Continue running (do not pause the timers)
 */

#define BI_SCHEMA_NUMBER  1035
#define BI_LAST_2X_SCHEMA_NUMBER  1015

#ifdef BILLINGS_PRO
#define BP_SCHEMA_NUMBER 4001
#undef BI_SCHEMA_NUMBER
#define BI_SCHEMA_NUMBER BP_SCHEMA_NUMBER
#endif

#define kBIPrimaryKeyIncrement 1000

extern NSString*  kBPHTTPRealm;


extern NSString* BPEncodePassword(NSString* username, NSString* password);



#define BIPROJECT_ENTITY_VALUE  101
#define BICLIENT_ENTITY_VALUE   102

#define BIIDLE_TIMERSACTION_WARN                   1           
#define BIIDLE_TIMERSACTION_AUTO_PAUSE             2
#define BIIDLE_TIMERSACTION_CONTINUE_RUNNING       3 

#define TIMED_TIMESLIP    101
#define FLAT_TIMESLIP     102
#define QUANTITY_TIMESLIP 103
#define EXPENSE_TIMESLIP  104
#define MANUAL_TIMESLIP   105
#define MILEAGE_TIMESLIP  106

#define MILEAGE_TYPE_MILES    0
#define MILEAGE_TYPE_KM       1

#define NUM_MINUTES_IN_HOUR   60
#define NUM_SECONDS_IN_HOUR   3600
#define NUM_SECONDS_IN_MIN    60
#define HALF_A_MINUTE_VALUE   30

#define PROJECT_STATECODE_ACTIVE  1001
#define PROJECT_STATECODE_COMPLETED 1002
#define PROJECT_STATECODE_CANCELLED 1003
#define PROJECT_STATECODE_ESTIMATE  1004

#define SLIP_NATURE_BILLABLE 101
#define SLIP_NATURE_PRO_BONO 102
#define SLIP_NATURE_MY_EYES_ONLY 103

#define URLREFERENCE_KIND_INVOICE    101
#define URLREFERENCE_KIND_ESTIMATE   102
#define URLREFERENCE_KIND_STATEMENT  103

#define BIINVOICE_STATE_NOTSENT   101
#define BIINVOICE_STATE_SENT      102

#define BICLIENTLIST_SORTBY_CLIENT_NAME  	1
#define BICLIENTLIST_SORTBY_ORG_NAME     	2
#define BICLIENTLIST_SORTBY_CLIENT_LASTNAME 3

#define BISEARCH_DOUBLE_CLICK_EDITS      1
#define BISEARCH_DOUBLE_CLICK_REVEALS    2


#define BIEXTRA_DATA_TYPE			10
#define BIEXTRA_STRING_TYPE			20
#define BIEXTRA_DATETIME_TYPE		30
#define BIEXTRA_DOUBLE_TYPE			40
#define BIEXTRA_FLOAT_TYPE			50
#define BIEXTRA_INT_TYPE			60



#define BICheckNumberIfNil(X)       if ( X == nil ) { X = [NSNumber numberWithDouble:0.0]; }
#define BIDefaultNumberBehaviour    [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain   \
																						   scale:2              \
																				raiseOnExactness:NO             \
																				 raiseOnOverflow:NO             \
																				raiseOnUnderflow:NO             \
																			 raiseOnDivideByZero:NO]

/* Mileage rates should be accurate to 3 decimal digits */
#define BIMileageRateNumberBehaviour    [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain   \
                                                                                               scale:3              \
																					raiseOnExactness:NO             \
                                                                                     raiseOnOverflow:NO             \
																					raiseOnUnderflow:NO             \
																				 raiseOnDivideByZero:NO]




/* ERROR KEYS */
extern NSString *BIErrorFilePathKey;
extern NSString *BIErrorSuspectObjectKey;

/* ACTUAL SUB PATH NAMES */
extern NSString* BIDatabaseStoragePath;
extern NSString* BIEstimatesPath;
extern NSString* BIInvoicesPath;
extern NSString* BIStatementsPath;
extern NSString* BPUploadPath;
extern NSString* BPLogsPath;
extern NSString* BPTemplatesPath;
extern NSString* BPAccountsPath;

extern NSString* BPLastSyncInfo;
extern NSString* BPLastSyncAttemptInfo;
extern NSString* BPIsSynchronizingInfo;
extern NSString* BPDatabaseInfo;

/* User defaults */
extern NSString* BILastQueriedImportFromAppNamed;
extern NSString* BIInvoicedSinceDate;

/* Project Change Notifications */

extern NSString* BIProjectStateChangedNotification;

extern NSString* BIClientBalanceChangedNotification;
extern NSString* BIClientRetainersBalanceChangedNotification;
extern NSString* BIClientUnbilledAmountChangedNotification;
extern NSString* BIClientIncompleteAmountChangedNotification;
extern NSString* BIClientOverdueAmountChangedNotification;

extern NSString* BITimedSlipCompletedNotification;
extern NSString* BITimedSlipNotCompletedNotification;

extern NSString* BITimedSlipStartTimerNotification;
extern NSString* BITimedSlipStopTimerNotification;

extern NSString* BIMachineIsIdleNotification;
extern NSString* BIMachineIsActiveNotification;

extern NSString* BIProjectAddedNotification;

extern NSString* BIInvoicePDFGeneratedNotification;

extern NSString* BIRecurringInvoicePastDueChangedNotification;

extern NSString* BIClientsCategoryChangedNotification;
extern NSString* BIClientCategoryRenamedNotification;

extern NSString* BIForeignAppIDConvertedToWorkingSlip;

extern NSString* BIBEXImportNotification;

extern NSString* MCDurationFormatterDefaultFormatChangedNotification;

extern NSString* BIResetInvalidTimeSlipTypeNotification;

extern NSString* BIExtraFieldNamesChangedNotification;

extern NSString* BISlipOwnerChangedNotification;


/* User Defaults Keys  -- BEGIN */
extern NSString* BIProjectShowExtraFields;
extern NSString* BINextInvoiceNumber;
extern NSString* BINextEstimateNumber;
extern NSString* BINextStatementNumber;
extern NSString* BIInvoiceNumPaddingLength;
extern NSString* BIEstimateNumPaddingLength;
extern NSString* BIStatementNumPaddingLength;
extern NSString* BIInvoicePrefix;
extern NSString* BIEstimatePrefix;
extern NSString* BIStatementPrefix;
extern NSString* BIClientListOtherClientsItemCollapsed;
extern NSString* BICustomTermsType;
extern NSString* BICustomTermsNumberOfDays;
extern NSString* BICustomTermsEndOfMonthPlus;
extern NSString* BICustomTermsEndOfMonthDays;
extern NSString* BICustomTermsEndOfNextMonthPlus;
extern NSString* BICustomTermsEndOfNextMonthDays;
/* User Defaults Keys  -- END */






typedef enum {
    BPSlipsWorkflowNew 			= 0,
    BPSlipsWorkflowWaiting 		= 1,
    BPSlipsWorkflowApproved  	= 2
} BPSlipsWorkflowState;


#define BPSlipApprovedState [NSNumber numberWithInt:BPSlipsWorkflowApproved]
#define BPSlipWaitingState [NSNumber numberWithInt:BPSlipsWorkflowWaiting]
#define BPSlipNotApprovedState [NSNumber numberWithInt:BPSlipsWorkflowNew]
#define BPSlipNewState [NSNumber numberWithInt:BPSlipsWorkflowNew]


typedef enum {
	BPDownloadServerNotReachable 	= 1,
	BPDownloadingNow 				= 2,
	BPDownloaded 					= 3,
	BPDownloadError 				= 10
} BPDownloadStatus;


typedef enum {
	BPNextUniqueNumberForeverIncrement			= 1,
	BPNextUniqueNumberYearlyIncrement			= 2
} BPNextUniqueNumberingScheme;

typedef enum {
    BPAppUnknownOperatingMode                   = 0,
    BPAppNormalOperatingMode                    = 1,
    BPAppLocalOnlyOperatingMode                 = 2,
    BPAppSampleDataOperatingMode                = 3
} BPAppOperatingMode;


typedef enum {
    BPAppLaunchNormalMode = 0,
    BPAppLaunchSampleDataMode = 1, // sample data for demo purposes
    BPAppLaunchResetKeychainMode = 4,
    BPAppLaunchDebugMigration = 5, // migrate b3 data for local debug purposes
    BPAppLaunchForceMigrationMode = 6, // show migration in first run
} BPAppLaunchMode;


extern NSString* BPSlipWorkflowStateChangedNotification;

/*!
 Posted when BPDownloadManager successfully (or fail) downloads the file related to a URLReference. The URLReference is the object in the notif
 */
extern NSString* BPURLReferenceDownloadSucceededNotification;
extern NSString* BPURLReferenceDownloadFailedNotification;


/*!
 Defaults used by punchcard to store the active timer per user.
 */
extern NSString* BPPunchcardActiveTimerEntriesByUser;


// These are used as base URLs for REST requests, and depend on runtime settings stored in user defaults
// TODO: define some, if needed
// See MCNetComm/MCNetCommGlobals.h (MCHostURLForService()) for more
extern NSString *kBPHTTPServiceName;
extern NSString *kBPAccessServiceName;
extern NSString *kBPTouchServiceName;
extern NSString *kBPTimecardServiceName;
extern NSString *kBPBackendServiceName;
extern NSURL *BPHostURLForService(NSString *serviceName);

#define BPHTTPHostURL()       BPHostURLForService(kBPHTTPServiceName)
#define BPAccessHostURL()     BPHostURLForService(kBPAccessServiceName)
#define BPTouchHostURL()      BPHostURLForService(kBPTouchServiceName)
#define BPTimecardHostURL()   BPHostURLForService(kBPTimecardServiceName)
#define BPBackendHostURL()    BPHostURLForService(kBPBackendServiceName)


#define BPCloudIDAllowedCharacters  @"1234567890abcdefghijklmnopqrstuvwxyz-"



@interface BISubstrateDefines : NSObject {
	
}
/*!
 Helps determine things like if the sync helper should run, whether certain panels should appear etc..
 */
+ (BPAppOperatingMode)appOperatingMode;

/*!
 This flag is set when the application launches based on the modifiers held by the user. We put it here because various layers of the app need to know without having access to the top level... This is different than appOperatingMode, but appLaunchMode can potentially affect appOperatingMode;
 */
+ (BPAppLaunchMode)appLaunchMode;
+ (void)setAppLaunchMode:(BPAppLaunchMode)launchMode;


/*!
 Specifies whether the app syncs or not as determined by the appOperatingMode; Helpful for things like menus.
 */
+ (BOOL)syncs;

+ (NSString*)billingsPath;
+ (NSString*)databaseFolderPath;
+ (NSString*)databaseFilePath;
+ (NSString*)databaseStoragePath; // app support + storage.bipdb
+ (NSString*)dbPath; // calls +databaseFolderPath
+ (NSString*)databaseInfoPath; // Info.plist in the Database folder -- might not have one
+ (NSString*)estimatesPath;
+ (NSString*)invoicesPath;
+ (NSString*)statementsPath;
+ (NSString*)metaDataPath;
+ (NSString*)logsPath;
+ (NSString*)templatesPath;
+ (NSString*)accountsPath; // storage when switching accounts
+ (NSString*)uploadPath; // queue to upload pdf's to cloud
+ (NSString*)lastSyncInfoPath; // bp users want to know when the last sync with changes was
+ (NSString*)lastSyncAttemptInfoPath; // bp users - when the last sync attempt happened. Value from the db may have timezone issue.
+ (NSString*)isSynchronizingInfoPath; // sometimes if we query the DO connection during the sync, it hangs for a while, so we check this file instead
+ (NSString*)billingsTemplatesPath;
+ (NSString*)billings2FullBackupPath;
+ (NSString*)backupPath;
+ (NSString*)touchSyncPath;

+ (NSString *)billingsSingleFilePath;

+ (NSDecimalNumber*)decimalNumberForNumber:(NSNumber*)aNumber;
+ (NSString*)tabDelimitedRepresentationOfObject:(id)obj usingFieldDicts:(NSArray*)fieldDicts;

// Deprecated in 2.0, remove by 3.0 - aj
+ (NSString*)estimatesTemplatePath;
+ (NSString*)invoicesTemplatePath;
+ (NSString*)statementsTemplatePath;
+ (NSString*)reportsPath;

+ (NSMutableDictionary*)plistRepresentationForObject:(id)theObject;
+ (void)restoreValuesForObject:(id)theObject fromPlist:(NSDictionary*)aDict excludingKeyPaths:(NSArray*)excludeKeyPaths;


+ (NSString*)paddedNumberWithNumber:(NSNumber*)aNumber padding:(int)paddingLen;


@end
