/*=========================================================================

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .NAME vtkKWRegistrationWizard - a class to manage application registration

#ifndef __vtkKWRegistrationWizard_h
#define __vtkKWRegistrationWizard_h

#include "vtkKWWizard.h"
#include <time.h> /* for time_t, until VTK provides a int64 */

class vtkKWComputerID;
class vtkKWFrame;
class vtkKWEntryWithLabel;
class vtkKWLabelWithLabel;
class vtkKWRadioButtonSetWithLabel;
class vtkKWLoadSaveButtonWithLabel;
class vtkKWText;

class VTK_EXPORT vtkKWRegistrationWizard : public vtkKWWizard
{
public:
  static vtkKWRegistrationWizard* New();
  vtkTypeRevisionMacro(vtkKWRegistrationWizard,vtkKWWizard);
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Check if the application is allowed to run according to the registration
  // settings in the registry. It will check for a valid license 
  // (VerifyLicenseKeyInRegistry()) or if we are running in Limited
  // mode (InLimitedMode()).
  virtual int IsApplicationAllowedToRun();

  // Description:
  // Invoke the dialog and display it in a modal manner.  This method returns
  // a zero if the dialog was killed or canceled, nonzero otherwise.
  virtual int Invoke();

  // Description:
  // Return the registration choice, after Invoke() is called.
  // For TRIAL_MODE and FULL_MODE, LicenseKey will be set to the key
  // that was valid for that choice.
  //BTX
  enum
  {
    INVALID_MODE         = 0,
    TRIAL_MODE           = 1,
    FULL_MODE            = 2,
    LIMITED_EDITION_MODE = 3
  };
  //ETX
  vtkGetMacro(RegistrationChoice, int);
  vtkGetStringMacro(LicenseKey);

  // Description:
  // Close this Wizard
  virtual void Cancel();
  virtual void OK();
  
  // Description:
  // Set the public and private encryption key corresponding to the application
  // Those are used to encrypt/decrypt licensing informations.
  vtkSetStringMacro(PublicEncryptionKey);
  vtkSetStringMacro(PrivateEncryptionKey);

  // Description:
  // Get the computer ID (i.e. the unique identifier as a string)
  const char* GetComputerId();

  // Description:
  // Get the licensing status as a string (i.e. in which mode we are
  // currently running, how many days are left, etc).
  // The status is output to a stream.
  virtual void GetCurrentLicenseStatusAsString(ostream &os);

  // Description:
  // Verify a license key
  // Return 1 if valid, 0 otherwise.
  virtual int VerifyLicenseKey(const char *license_key);

  // Description:
  // Get license key from license file and store in in buffer
  // Return 1 on success, 0 otherwise.
  virtual int GetLicenseKeyFromFile(const char *fname, char *buffer);

  // Description:
  // Set/Get the license key file name expected for this application (as send
  // by the registration server or by ourselves). This is a basename, not
  // a full path, i.e. this is used to indicate to the user what filename
  // is expected to be attached to his confirmation email.
  vtkSetStringMacro(ExpectedLicenseKeyFileName);
  vtkGetStringMacro(ExpectedLicenseKeyFileName);

  // Description:
  // Retrieve a license key online and store it in buffer.
  // Email is optional.
  // Return 1 on success, 0 otherwise.
  virtual int GetLicenseKeyOnline(char *buffer, const char *email = 0);

  // Description:
  // Set/Get the registration URL, i.e. the web address where a license
  // key can be obtained manually.
  vtkSetStringMacro(RegistrationURL);
  vtkGetStringMacro(RegistrationURL);

  // Description:
  // Get a license key expiration date as a time_t result (number of
  // seconds since Epoch).
  // Return 0 on error, number of seconds otherwise.
  virtual time_t GetLicenseKeyExpirationDate(const char *license_key);

  // Description:
  // Set a most recent date for the current application. Default to 0.
  // If different than 0, this date will be compared to the current date
  // to check if the user has set his clock in the past to bypass
  // the registration. 
  vtkSetMacro(MostRecentDate, time_t);
  vtkGetMacro(MostRecentDate, time_t);

  // Description:
  // Store a license key to registry.
  // Retrieve a license key that was stored in the registry.
  // Remove a license key that was stored in the registry.
  // Retrieve and verify a license key that was stored in the registry.
  // Set the registry subkey (default to Setup) and key (default to 
  // LicenseKey) used to store and retrieve the license key.
  // Return 1 on success, 0 otherwise.
  virtual int StoreLicenseKeyInRegistry(const char *license_key);
  virtual int RetrieveLicenseKeyFromRegistry(char *buffer);
  virtual int RemoveLicenseKeyFromRegistry();
  virtual int VerifyLicenseKeyInRegistry();
  vtkGetStringMacro(LicenseKeyRegistrySubKey);
  vtkSetStringMacro(LicenseKeyRegistrySubKey);
  vtkGetStringMacro(LicenseKeyRegistryKey);
  vtkSetStringMacro(LicenseKeyRegistryKey);

  // Description:
  // Set/Get if this application supports a Trial Mode.
  vtkSetClampMacro(SupportTrialMode, int, 0, 1);
  vtkBooleanMacro(SupportTrialMode, int);
  vtkGetMacro(SupportTrialMode, int);

  // Description:
  // Query if we are in Trial Mode already.
  // Will check if VerifyLicenseKeyInRegistry() is successfull and check if
  // an expiration date is set in the future.
  // Return 1 if in trial mode, 0 otherwise.
  virtual int InTrialMode();

  // Description:
  // Query if Trial Mode has expired.
  // Will check if VerifyLicenseKeyInRegistry() failed (i.e. the license key,
  // including a Trial Mode license key, is not valid anymore) and check if
  // an expiration date is set in the past.
  // Return 1 if has expired, 0 otherwise.
  virtual int HasTrialModeExpired();

  // Description:
  // Set/Get if the name of the Full mode. 
  // Default to: full.
  vtkSetStringMacro(FullModeName);
  vtkGetStringMacro(FullModeName);

  // Description:
  // Query if we are in Full Mode already.
  // Will check if VerifyLicenseKeyInRegistry() is successfull and check if
  // an expiration date is set to something higher than the trial period
  // expiration date (typically it will be much larger).
  // IsLicenseKeyInFullMode() will test if a given license_key, if valid,
  // would put us in Full Mode.
  // Return 1 if in full mode, 0 otherwise.
  virtual int InFullMode();
  virtual int IsLicenseKeyInFullMode(const char *license_key);

  // Description:
  // Set/Get if this application supports a Limited mode.
  vtkSetClampMacro(SupportLimitedEditionMode, int, 0, 1);
  vtkBooleanMacro(SupportLimitedEditionMode, int);
  vtkGetMacro(SupportLimitedEditionMode, int);

  // Description:
  // Query if we are in Limited Mode already.
  // Will check if RetrieveLimitedEditionModeFromRegistry() is successfull and
  // the mode retrieved is true.
  // Return 1 if in LE mode, 0 otherwise.
  virtual int InLimitedEditionMode();

  // Description:
  // Store the Limited Mode flag to registry
  // Retrieve a Limited Mode flag that was stored in the registry.
  // Remove a Limited Mode flag that was stored in the registry.
  // Set the registry subkey (default to Setup) and key (default to 
  // LimitedEditionMode) used to store and retrieve the LE mode.
  // Return 1 on success, 0 otherwise.
  virtual int StoreLimitedEditionModeInRegistry(int mode);
  virtual int RetrieveLimitedEditionModeFromRegistry(int *mode);
  virtual int RemoveLimitedEditionModeFromRegistry();
  vtkGetStringMacro(LimitedEditionModeRegistrySubKey);
  vtkSetStringMacro(LimitedEditionModeRegistrySubKey);
  vtkGetStringMacro(LimitedEditionModeRegistryKey);
  vtkSetStringMacro(LimitedEditionModeRegistryKey);

  // Description:
  // Callbacks (registration type)
  virtual int PromptRegistrationType();
  virtual int ProcessRegistrationType();

  // Description:
  // Callbacks (purchase app)
  virtual int PromptPurchaseApplication();
  virtual int ProcessPurchaseApplication();

  // Description:
  // Callbacks (internet connection)
  virtual int PromptInternetConnection();
  virtual int ProcessInternetConnection();

  // Description:
  // Callbacks (trial mode)
  virtual int PromptOnlineRegistrationParameters();
  virtual int ProcessOnlineRegistrationParameters();
  virtual int PromptOnlineRegistrationConfirmation();

  // Description:
  // Callbacks (full mode)
  virtual int PromptOfflineRegistrationParameters();
  virtual int ValidateOfflineRegistrationParameters();
  virtual int ProcessOfflineRegistrationParameters();
  virtual int PromptOfflineRegistrationConfirmation();

  // Description:
  // Callbacks (limited edition mode)
  virtual int PromptLimitedEditionModeConfirmation();

  // Description:
  // Get the ComputerID object
  vtkGetObjectMacro(ComputerID, vtkKWComputerID);

protected:
  vtkKWRegistrationWizard();
  ~vtkKWRegistrationWizard();

  // Description:
  // Create the widget
  virtual void CreateWidget();

  int Invoked;
  int SupportTrialMode;
  int SupportLimitedEditionMode;

  int RegistrationChoice;
  vtkSetStringMacro(LicenseKey);
  char *LicenseKey;

  vtkKWComputerID *ComputerID;

  char *PublicEncryptionKey;
  char *PrivateEncryptionKey;

  char *LicenseKeyRegistrySubKey;
  char *LicenseKeyRegistryKey;
  
  char *LimitedEditionModeRegistrySubKey;
  char *LimitedEditionModeRegistryKey;
  
  char *ExpectedLicenseKeyFileName;
  char *RegistrationURL;

  char *FullModeName;

  virtual void GetSubTitleLabelGivenRegistrationChoice(int c, ostream &os);

  // License key
                                                       
  virtual int ConfigureComputerID();
  virtual int CheckLicenseFramework();

  // Registration type

  virtual void CreateRegistrationTypePage();
  virtual void SetRegistrationTypeInfoLabel(const char *str);

  vtkKWFrame                   *RegistrationTypeFrame;
  vtkKWLabelWithLabel          *RegistrationTypeInfoLabel;
  vtkKWRadioButtonSetWithLabel *RegistrationTypeChoice;
  
  // Purchase

  virtual void CreatePurchaseApplicationPage();

  vtkKWFrame                   *PurchaseApplicationParametersFrame;
  vtkKWText                    *PurchaseApplicationTextArea;

  // Internet connection

  virtual void CreateInternetConnectionPage();

  vtkKWFrame                   *InternetConnectionFrame;
  vtkKWRadioButtonSetWithLabel *InternetConnectionChoice;
  
  // Register Online

  virtual void CreateOnlineRegistrationParametersPage();

  vtkKWFrame          *OnlineRegistrationParametersFrame;
  vtkKWEntryWithLabel *OnlineRegistrationEmailEntry;

  virtual void CreateOnlineRegistrationConfirmationPage();

  vtkKWFrame          *OnlineRegistrationConfirmationFrame;
  vtkKWLabelWithLabel *OnlineRegistrationConfirmationLabel;
  
  // Register Offline

  virtual void CreateOfflineRegistrationParametersPage();
  virtual void SetOfflineRegistrationErrorLabel(const char *str);

  vtkKWFrame                   *OfflineRegistrationParametersFrame;
  vtkKWText                    *OfflineRegistrationTextArea;
  vtkKWLoadSaveButtonWithLabel *OfflineRegistrationLicenseFileButton;
  vtkKWLabelWithLabel          *OfflineRegistrationErrorLabel;

  virtual void CreateOfflineRegistrationConfirmationPage();

  vtkKWFrame          *OfflineRegistrationConfirmationFrame;
  vtkKWLabelWithLabel *OfflineRegistrationConfirmationLabel;
  
  // Limited Mode

  virtual void CreateLimitedEditionModeConfirmationPage();
  virtual const char* GetLimitedEditionModeName();

  // Build Date

  time_t MostRecentDate;
  virtual int IsCurrentDateBeforeMostRecentDate();

private:
  vtkKWRegistrationWizard(const vtkKWRegistrationWizard&); // Not implemented
  void operator=(const vtkKWRegistrationWizard&); // Not Implemented
};


#endif

