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

  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.

=========================================================================*/
#include "vtkKWApplicationPro.h"

#include "vtkDynamicLoader.h"
#include "vtkTimerLog.h"
#include "vtkObjectFactory.h"
#include "vtkImageData.h"
#include "vtkRenderWindow.h"
#include "vtkgl.h"

#include "vtkKWFrameWithLabel.h"
#include "vtkKWInternationalization.h"
#include "vtkKWMessageDialog.h"
#include "vtkKWRegistryHelper.h"
#include "vtkKWWindow.h"
#include "vtkKWProcessStatistics.h"

#include "vtkKWWidgetsConfigure.h" // Needed for KWWidgets_BUILD_VTK_WIDGETS
#include "vtkKWWidgetsProConfigure.h" 
#include "vtkKWWidgetsProBuildConfigure.h" // KWWidgetsPro_INSTALL_DATA_DIR
#ifdef KWWidgets_BUILD_VTK_WIDGETS
#include "vtkKWCommonProConfigure.h" // Needed for KWCommonPro_USE_XML_RW
#endif

#include "vtkKWEGPUInfoList.h"
#include "vtkKWEGPUInfo.h"
#include "vtkKWEGPUVolumeRayCastMapper.h"

#include <vtksys/SystemTools.hxx>
#include <vtksys/SystemInformation.hxx>

#ifdef KWCommonPro_USE_XML_RW
#include "XML/vtkXMLIOBase.h"
#endif

#ifdef KWWidgetsPro_USE_Flickcurl
#include "flickcurl.h"
#include <stdio.h>
#include <stdlib.h>
#include "vtkPNGWriter.h"
#include "vtkErrorCode.h"
#endif

#include <time.h>

const char *vtkKWApplicationPro::FlickrRegSubKey = "Flickr";
const char *vtkKWApplicationPro::FlickrApplicationKeyRegKey = "FlickrApplicationKey";
const char *vtkKWApplicationPro::FlickrSharedSecretRegKey = "FlickrSharedSecret";
const char *vtkKWApplicationPro::FlickrAuthenticationTokenRegKey = "FlickrAuthenticationToken";
const char *vtkKWApplicationPro::UseGPURenderingRegKey = "UseGPURendering";

//----------------------------------------------------------------------------
vtkCxxRevisionMacro( vtkKWApplicationPro, "$Revision: 1.97 $");
vtkStandardNewMacro( vtkKWApplicationPro );

extern "C" int Kwwidgetspro_Init(Tcl_Interp *interp);

//----------------------------------------------------------------------------
Tcl_Interp *vtkKWApplicationPro::InitializeTcl(int argc, 
                                               char *argv[], 
                                               ostream *err)
{
  Tcl_Interp *interp = vtkKWApplication::InitializeTcl(argc, argv, err);
  if (interp)
    {
    Kwwidgetspro_Init(interp);
    }
  
  // As a convenience, try to find the text domain binding for
  // KWWidgetsPro right now

  vtkKWInternationalization::FindTextDomainBinding(
    "KWWidgetsPro", KWWidgetsPro_INSTALL_DATA_DIR);

  return interp;
}

//----------------------------------------------------------------------------
vtkKWApplicationPro::vtkKWApplicationPro()
{
  this->ExpireTime      = 0;
  this->TestingMode     = 0;
  this->UseGPURendering = 1;

  this->PrimaryCopyright      = NULL;
  this->PurchaseURL           = NULL;
  this->CompanyName           = NULL;
  this->CompanySalesContact   = NULL;
  this->CompanySupportContact = NULL;

  this->FlickrApplicationKey      = NULL;
  this->FlickrSharedSecret        = NULL;
  this->FlickrAuthenticationToken = NULL;
  
  // Need to update KWVolView\CMake\KWVolViewCreateExecutableMacros.cmake
  // as well...

  this->SetCompanyName("Kitware, Inc.");
  this->SetCompanySalesContact("mailto:kitware@kitware.com / (518) 371-3971");
  this->SetCompanySupportContact("mailto:support@kitware.com / (518) 371-3971");

  // GUI style & consistency

  vtkKWFrameWithLabel::SetDefaultAllowFrameToCollapse(1);
  vtkKWFrameWithLabel::SetDefaultLabelCaseToUppercaseFirst();
  vtkKWFrameWithLabel::SetDefaultLabelFontWeightToBold();

#ifdef KWCommonPro_USE_XML_RW
  vtkXMLIOBase::SetDefaultCharacterEncoding(this->CharacterEncoding);
#endif
}

//----------------------------------------------------------------------------
vtkKWApplicationPro::~vtkKWApplicationPro()
{
  this->SetPrimaryCopyright(NULL);
  this->SetPurchaseURL(NULL);
  this->SetCompanyName(NULL);
  this->SetCompanySalesContact(NULL);
  this->SetCompanySupportContact(NULL);

  this->SetFlickrApplicationKey(NULL);
  this->SetFlickrSharedSecret(NULL);
  this->SetFlickrAuthenticationToken(NULL);
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::PrepareForDelete()
{
  this->Superclass::PrepareForDelete();
}

//----------------------------------------------------------------------------
int vtkKWApplicationPro::IsAllowedToRun()
{
  return 1;
}

//----------------------------------------------------------------------------
int vtkKWApplicationPro::InvokeRegistrationWizard(vtkKWWindowBase *)
{
  return 1;
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::SetCharacterEncoding(int val)
{
  if (val == this->CharacterEncoding)
    {
    return;
    }

  if (val < VTK_ENCODING_NONE)
    {
    val = VTK_ENCODING_NONE;
    }
  else if (val > VTK_ENCODING_UNKNOWN)
    {
    val = VTK_ENCODING_UNKNOWN;
    }

  this->CharacterEncoding = val;
  
#ifdef KWCommonPro_USE_XML_RW
  vtkXMLIOBase::SetDefaultCharacterEncoding(this->CharacterEncoding);
#endif

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::AddSystemInformation(ostream &os)
{
  this->Superclass::AddSystemInformation(os);

  vtksys::SystemInformation sysinfo;
  sysinfo.RunCPUCheck();
  sysinfo.RunOSCheck();
  sysinfo.RunMemoryCheck();
  
  os << k_("OS Name") << ": " 
     << sysinfo.GetOSName() << endl

     << k_("OS Release") << ": " 
     << sysinfo.GetOSRelease() << endl

     << k_("OS Version") << ": " 
     << sysinfo.GetOSVersion() << endl

     << k_("OS Platform") << ": " 
     << sysinfo.GetOSPlatform() << endl;

  os << k_("Number Of Physical CPU(s)") << ": " 
     << sysinfo.GetNumberOfPhysicalCPU() << endl

     << k_("Number Of Logical CPU(s)") << ": " 
     << sysinfo.GetNumberOfLogicalCPU() << endl;

  os << k_("Is 64 Bits") << ": " 
     << (sysinfo.Is64Bits() ? k_("Yes") : k_("No")) << endl;

  // Most/all of these above are wrong on 64 bits systems :(

  os << k_("Available Virtual Memory (MB)") << ": " 
     << sysinfo.GetAvailableVirtualMemory() << endl

     << k_("Available Physical Memory (MB)") << ": " 
     << sysinfo.GetAvailablePhysicalMemory() << endl

     << k_("Total Virtual Memory (MB)") << ": " 
     << sysinfo.GetTotalVirtualMemory() << endl

     << k_("Total Physical Memory (MB)") << ": " 
     << sysinfo.GetTotalPhysicalMemory() << endl

     << k_("Processor Clock Frequency") << ": " 
     << sysinfo.GetProcessorClockFrequency() << endl;

#if 0
  os << k_("Vendor ID") << ": " 
     << sysinfo.GetVendorID() << endl

     << k_("Extended Processor Name") << ": " 
     << sysinfo.GetExtendedProcessorName() << endl

     << k_("Processor Cache Size") << ": " 
     << sysinfo.GetProcessorCacheSize() << endl

  os << k_("Vendor String") << ": " 
     << sysinfo.GetVendorString() << endl

     << k_("Type ID") << ": " 
     << sysinfo.GetTypeID() << endl

     << k_("Family ID") << ": " 
     << sysinfo.GetFamilyID() << endl

     << k_("Model ID") << ": " 
     << sysinfo.GetModelID() << endl

     << k_("Stepping Code") << ": " 
     << sysinfo.GetSteppingCode() << endl

     << k_("Processor Serial Number") << ": " 
     << sysinfo.GetProcessorSerialNumber() << endl

     << k_("Logical Processors Per Physical") << ": " 
     << sysinfo.GetLogicalProcessorsPerPhysical() << endl

     << k_("Processor API CID") << ": " 
     << sysinfo.GetProcessorAPICID() << endl;
#endif

  // OpenGL

  // Sadly, we need an OpenGL context for this one
  // therefore we may need to create a renderwindow temporarily.

  vtkRenderWindow *renwin = vtkRenderWindow::New();
  renwin->SetSize(1, 1);
  renwin->BordersOff();
  renwin->Render();

  const char *gl_vendor = NULL;
#ifndef __APPLE__
  gl_vendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
#endif
  const char *gl_version =
    reinterpret_cast<const char *>(glGetString(GL_VERSION));
  const char *gl_renderer =
    reinterpret_cast<const char *>(glGetString(GL_RENDERER));

  if (gl_vendor)
    {
    os << k_("OpenGL Vendor") << ": " << gl_vendor << endl;
    }
  if (gl_version)
    {
    os << k_("OpenGL Version") << ": " << gl_version << endl;
    }
  if (gl_renderer)
    {
    os << k_("OpenGL Renderer") << ": " << gl_renderer << endl;
    }

  // GPU

  vtkKWEGPUInfoList *l = vtkKWEGPUInfoList::New();
  l->Probe();
  if (l->GetNumberOfGPUs())
    {
    vtkKWEGPUInfo *info = l->GetGPUInfo(0);
    vtkIdType value;
    value = info->GetDedicatedVideoMemory();
    os << k_("GPU VRAM") << ": " << value / (1024 * 1024) << " MB" << endl;
    }
  l->Delete();

  vtkKWEGPUVolumeRayCastMapper *mapper = vtkKWEGPUVolumeRayCastMapper::New();
  os << k_("GPU Rendering") << ": " << (mapper->IsRenderSupported(renwin, NULL) ? k_("Supported") : k_("NOT supported")) << endl;
  mapper->Delete();

  os << k_("Use GPU Rendering") << ": " 
     << (this->UseGPURendering ? k_("Yes") : k_("No")) << endl;

  if (renwin)
    {
    renwin->Delete();
    }
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::AddAboutText(ostream &os)
{
  this->Superclass::AddAboutText(os);
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::AddAboutCopyrights(ostream &os)
{
  if (this->PrimaryCopyright && *this->PrimaryCopyright)
    {
    os << this->PrimaryCopyright << endl;
    }

  char buffer[500];
  sprintf(buffer, ks_("Copyrights|All rights reserved %s"), "Kitware Inc.");
  os << "Kitware Inc.  --  kitware@kitware.com" << endl 
     << buffer << endl
     << "28 Corporate Drive" << endl
     << "Clifton Park NY 12065" << endl
     << "(518) 371-3971" << endl
     << endl;

  this->Superclass::AddAboutCopyrights(os);

#ifdef KWWidgetsPro_USE_Flickcurl
  os << "This product includes Flickcurl software (http://librdf.org/flickcurl/) created by David Beckett (http://purl.org/net/dajobe/)" << endl;
#endif
#ifdef KWCommonPro_USE_CTNLIB
  os << "CTN DICOM library Copyright (c) 1993-1994 RSNA and Washington "
     << "University." << endl;
#endif
#ifdef KWCommonPro_USE_GDCM
  os << "GDCM library (c) 1993-2005 CREATIS (c) 2006-2009 Mathieu Malaterre "
     << "(http://gdcm.sourceforge.net)." << endl;
#endif
#ifndef _WIN32
  os << "MPEG encode Copyright (c) 1995 The Regents of the University of "
     << "California." << endl;
  os << "FFMPEG (svn revision 4910): " 
     << endl << "     Copyright (c) 1999-2008 Fabrice Bellard"
     << endl << "     Available from -- http://ffmpeg.mplayerhq.hu/index.html" 
     << endl << "     Licensed under the Lesser Gnu Public License, " 
             << "http://www.gnu.org/copyleft/lesser.html" << endl;
#endif
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::SetExpireTime(double arg)
{
  if (this->ExpireTime == arg)
    {
    return;
    }
  
  this->ExpireTime = arg;
  this->Modified();

  this->HasExpired(); // Considering the new time, have we expired ?
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::SetExpireTime(const char *str)
{
  if (!str || !*str)
    {
    vtkErrorMacro("Can't set expire time from empty string!");
    return;
    }

  // YYYY-MM-DD HH:MM:SS

  int year, month, day, hour, min, second;
  
  if (sscanf(str, "%d-%d-%d %d:%d:%d", 
             &year, &month, &day, &hour, &min, &second) != 6)
    {
    vtkErrorMacro("Can't set expire time from invalid string!" << str);
    }

  time_t timer;
  time(&timer);

  struct tm *localtime_ptr = localtime(&timer);

  struct tm newtime;
  newtime.tm_year = year - 1900;
  newtime.tm_mon = month - 1;
  newtime.tm_mday = day;
  newtime.tm_hour = hour;
  newtime.tm_min = min;
  newtime.tm_sec = second;
  newtime.tm_isdst = localtime_ptr->tm_isdst;

  this->SetExpireTime((double)mktime(&newtime));
}

//----------------------------------------------------------------------------
int vtkKWApplicationPro::HasExpired()
{
  if (this->ExpireTime > 0 && 
      this->ExpireTime < vtkTimerLog::GetUniversalTime())
    {
    char buffer[500];
    sprintf(
      buffer,
      k_("This evaluation version of %s expired. Please download a new "
         "version online at %s, or contact %s at %s."),
      this->GetPrettyName(),
      this->GetPurchaseURL(),
      this->GetCompanyName(),
      this->GetCompanySupportContact()
      );
    vtkKWMessageDialog::PopupMessage(
      this, NULL, 
      ks_("Application Expired Dialog|Title|This application expired!"),
      buffer, vtkKWMessageDialog::ErrorIcon);
    this->Exit();
    return 1;
    }

  return 0;
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::ParseCommandLineArguments(int argc, char **argv)
{ 
  this->Superclass::ParseCommandLineArguments(argc, argv);
  
  int index = 0, pos = 0;
  int i, nb_windows = this->GetNumberOfWindows();

  // Command line args: geometry 
  
  if (this->CheckForValuedArgument(argc, argv, "--geometry", index, pos) 
      == VTK_OK ||
      this->CheckForValuedArgument(argc, argv, "--g", index, pos) 
      == VTK_OK)
    {
    for (i = 0; i < nb_windows; i++)
      {
      vtkKWWindowBase *win = this->GetNthWindow(i);
      if (win)
        {
        win->SetGeometry(argv[index] + pos);
        }
      }
    }

  // Command line args: no panels
  
  if (this->CheckForArgument(argc, argv, "--no-panels", index) 
      == VTK_OK ||
      this->CheckForArgument(argc, argv, "--np", index) 
      == VTK_OK)
    {
    for (i = 0; i < nb_windows; i++)
      {
      vtkKWWindow *win = vtkKWWindow::SafeDownCast(this->GetNthWindow(i));
      if (win)
        {
        win->MainPanelVisibilityOff();
        win->SecondaryPanelVisibilityOff();
        }
      }
    }

  // Command line args: testing mode
  
  if (vtkKWApplication::CheckForArgument(
        argc, argv, "--testing", index) == VTK_OK)
    {
    this->SetTestingMode(1);
    }

#ifdef KWWidgetsPro_USE_Flickcurl
  // Command line args: Flickr
  
  if (vtkKWApplication::CheckForValuedArgument(
        argc, argv, "--flickr-api-key", index, pos) == VTK_OK)
    {
    this->SetFlickrApplicationKey(argv[index] + pos);
    }

  if (vtkKWApplication::CheckForValuedArgument(
        argc, argv, "--flickr-shared-secret", index, pos) == VTK_OK)
    {
    this->SetFlickrSharedSecret(argv[index] + pos);
    }

  if (vtkKWApplication::CheckForValuedArgument(
        argc, argv, "--flickr-auth-token", index, pos) == VTK_OK)
    {
    this->SetFlickrAuthenticationToken(argv[index] + pos);
    }
#endif
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::Start(int argc, char*argv[])
{
  // Check if we can run

  if (this->InExit)
    {
    return;
    }

  while (!this->IsAllowedToRun())
    {
    if (this->Exit())
      {
      return;
      }
    }

  this->Superclass::Start(argc, argv);
}

//----------------------------------------------------------------------------
int vtkKWApplicationPro::SendScreenshotToFlickr()
{
  return 0;
}

//----------------------------------------------------------------------------
#ifdef KWWidgetsPro_USE_Flickcurl
static void vtkKWApplicationProFlickcurlMessageHandler(
  void *user_data, const char *message)
{
  vtkKWApplicationPro *app = (vtkKWApplicationPro*)user_data;
  vtkErrorWithObjectMacro(app, << "Flickcurl ERROR: " << message);
}
#endif

//----------------------------------------------------------------------------
int vtkKWApplicationPro::SendImageToFlickr(vtkImageData *img,
                                           const char *api_key,
                                           const char *shared_secret,
                                           const char *auth_token,
                                           const char *title,
                                           const char *description,
                                           const char *tags,
                                           int is_public)
{
  if (!img)
    {
    vtkErrorMacro("Failed uploading image to Flickr! (NULL image pointer)");
    return 0;
    }

#ifdef KWWidgetsPro_USE_Flickcurl

  int error_code;

  // Save the image to a file

  std::string temp_filename;
#ifdef _WIN32
  temp_filename += _tempnam(0, "flickr");
#else
  temp_filename += tempnam(0, "flickr");
#endif
  temp_filename += ".png";

  vtkPNGWriter *png_w = vtkPNGWriter::New();
  png_w->SetInput(img);
  png_w->SetFileName(temp_filename.c_str());
  png_w->Write();
  error_code = png_w->GetErrorCode();
  png_w->Delete();
  if (error_code != vtkErrorCode::NoError)
    {
    vtkErrorMacro(
      << "Failed uploading image to Flickr! ("
      << vtkErrorCode::GetStringFromErrorCode(error_code) << ")");
    return 0;
    }

  // Initialize Flickcurl

  flickcurl_init();
  flickcurl *fc = flickcurl_new();

  flickcurl_set_error_handler(
    fc, vtkKWApplicationProFlickcurlMessageHandler, this);

  // API key, shared secret and authentication token are all required

  flickcurl_set_api_key(
    fc, api_key ? api_key : this->FlickrApplicationKey);
  flickcurl_set_shared_secret(
    fc, shared_secret ? shared_secret : this->FlickrSharedSecret);
  flickcurl_set_auth_token(
    fc, auth_token ? auth_token : this->FlickrAuthenticationToken);

  // Upload parameters

  flickcurl_upload_params params;
  memset(&params, '\0', sizeof(flickcurl_upload_params)); 

  params.photo_file = temp_filename.c_str();
  params.title = title;
  params.description = description;
  params.tags = tags;
  params.is_public = is_public;
  params.is_friend = 0;
  params.is_family = 0;
  params.safety_level = 1;
  params.content_type = 2;

  // This is not async uppload, this may take a little bit

  vtkKWWindowBase *win = this->GetNthWindow(0);
  if (win)
    {
    win->SetStatusText("Sending image to Flickr...");
    }

  error_code = vtkErrorCode::NoError;
  flickcurl_upload_status *status = 
    flickcurl_photos_upload_params(fc, &params);
  if (status == NULL)
    {
    vtkErrorMacro("Failed uploading image to Flickr!");
    error_code = vtkErrorCode::UnknownError;
    }
  else
    {
    flickcurl_free_upload_status(status);
    }
  
  flickcurl_free(fc);
  flickcurl_finish();

  // Remove image file
  
  vtksys::SystemTools::RemoveFile(temp_filename.c_str());

  if (win)
    {
    win->SetStatusText(NULL);
    }
  
  return (error_code == vtkErrorCode::NoError) ? 1 : 0;

#else
  (void)api_key;
  (void)shared_secret;
  (void)auth_token;
  (void)title;
  (void)description;
  (void)tags;
  (void)is_public;

  return 0;
#endif
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::SetUseGPURendering(int arg)
{ 
  if (this->UseGPURendering == arg)
    {
    return;
    }

  this->UseGPURendering = arg;
  this->Modified();

  this->InvokeEvent(vtkKWApplicationPro::UseGPURenderingChangedEvent, &arg);
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::RestoreApplicationSettingsFromRegistry()
{ 
  this->Superclass::RestoreApplicationSettingsFromRegistry();

  // Use GPU Rendering

  if (this->HasRegistryValue(
        2, "RunTime", vtkKWApplicationPro::UseGPURenderingRegKey))
    {
    this->SetUseGPURendering(
      this->GetIntRegistryValue(
        2, "RunTime", vtkKWApplicationPro::UseGPURenderingRegKey));
    }

#ifdef KWWidgetsPro_USE_Flickcurl
  // Flickr Settings

  char buffer[vtkKWRegistryHelper::RegistryKeyValueSizeMax];

  if (this->HasRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrApplicationKeyRegKey) &&
      this->GetRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrApplicationKeyRegKey, buffer) &&
      *buffer)
    {
    this->SetFlickrApplicationKey(buffer);
    }

  if (this->HasRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrSharedSecretRegKey) &&
      this->GetRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrSharedSecretRegKey, buffer) &&
      *buffer)
    {
    this->SetFlickrSharedSecret(buffer);
    }

  if (this->HasRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrAuthenticationTokenRegKey) &&
      this->GetRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrAuthenticationTokenRegKey, buffer) &&
      *buffer)
    {
    this->SetFlickrAuthenticationToken(buffer);
    }
#endif
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::SaveApplicationSettingsToRegistry()
{ 
  this->Superclass::SaveApplicationSettingsToRegistry();

  // Use GPU Rendering

  this->SetRegistryValue(
    2, "RunTime", vtkKWApplicationPro::UseGPURenderingRegKey, "%d", 
    this->GetUseGPURendering());

#ifdef KWWidgetsPro_USE_Flickcurl
  // Flickr Settings

  if (this->GetFlickrApplicationKey())
    {
    if (*this->GetFlickrApplicationKey())
      {
      this->SetRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrApplicationKeyRegKey,
        this->GetFlickrApplicationKey());
      }
    else if (this->HasRegistryValue(
               0, 
               vtkKWApplicationPro::FlickrRegSubKey, 
               vtkKWApplicationPro::FlickrApplicationKeyRegKey))
      {
      this->DeleteRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrApplicationKeyRegKey);
      }
    }

  if (this->GetFlickrSharedSecret())
    {
    if (*this->GetFlickrSharedSecret())
      {
      this->SetRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrSharedSecretRegKey,
        this->GetFlickrSharedSecret());
      }
    else if (this->HasRegistryValue(
               0, 
               vtkKWApplicationPro::FlickrRegSubKey, 
               vtkKWApplicationPro::FlickrSharedSecretRegKey))
      {
      this->DeleteRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrSharedSecretRegKey);
      }
    }

  if (this->GetFlickrAuthenticationToken())
    {
    if (*this->GetFlickrAuthenticationToken())
      {
      this->SetRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrAuthenticationTokenRegKey,
        this->GetFlickrAuthenticationToken());
      }
    else if (this->HasRegistryValue(
               0, 
               vtkKWApplicationPro::FlickrRegSubKey, 
               vtkKWApplicationPro::FlickrAuthenticationTokenRegKey))
      {
      this->DeleteRegistryValue(
        0, 
        vtkKWApplicationPro::FlickrRegSubKey, 
        vtkKWApplicationPro::FlickrAuthenticationTokenRegKey);
      }
    }
#endif
}

//----------------------------------------------------------------------------
void vtkKWApplicationPro::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "TestingMode: " 
     << (this->TestingMode ? "On" : "Off") << endl;
  os << indent << "ExpireTime: " << this->ExpireTime  << endl;
  os << indent << "PrimaryCopyright: " 
     << (this->PrimaryCopyright ? this->PrimaryCopyright : "None") << endl;
  os << indent << "PurchaseURL: " 
     << (this->PurchaseURL ? this->PurchaseURL : "None") << endl;
  os << indent << "CompanyName: " 
     << (this->CompanyName ? this->CompanyName : "None") << endl;
  os << indent << "CompanySalesContact: " 
     << (this->CompanySalesContact ? this->CompanySalesContact : "None") << endl;
  os << indent << "CompanySupportContact: " 
     << (this->CompanySupportContact ? this->CompanySupportContact : "None") << endl;
}
