//==============================================
//  copyright            : (C) 2003-2005 by Will Stokes
//==============================================
//  This program is free software; you can redistribute it
//  and/or modify it under the terms of the GNU General
//  Public License as published by the Free Software
//  Foundation; either version 2 of the License, or
//  (at your option) any later version.
//==============================================

//Systemwide includes
#include <qapplication.h>
#include <qlayout.h>
#include <qtranslator.h>
#include <qtextcodec.h>
#include <qdir.h>
#include <iostream>

//PLATFORM_SPECIFIC_CODE
#if defined(Q_OS_MACX)
#include <CoreFoundation/CFURL.h>
#include <CoreFoundation/CFBundle.h>
#endif

//PLATFORM_SPECIFIC_CODE
//VC7 or later, building with pre-VC7 runtime libraries
#if defined(Q_OS_WIN)
extern "C" long _ftol( double ); //defined by VC6 C libs
extern "C" long _ftol2( double dblSource ) { return _ftol( dblSource ); }

#include <stdlib.h>
#endif

//Projectwide includes
#include "gui/cursors.h"
#include "gui/window.h"
#include "gui/dialogs/alertDialog.h"
#include "gui/welcomeWindow/welcomeWindow.h"
#include "backend/tools/guiTools.h"
#include "config.h"
#include "configuration/configuration.h"
#include "configuration/layoutSettingsWidget.h"
#include "backend/tools/fileTools.h"

/*! \mainpage
 *  AlbumShaper is a Qt app which allows easy hierarchical
 *  photo album creation and editing using a drag-n-drop interface.
 */

int main( int argc, char **argv)
{
  //create app
  QApplication a(argc, argv);
  
  //----------------------------------------------
  //set material path

  //PLATFORM_SPECIFIC_CODE

  //if using mac os x material dir in bundle
  #if defined(Q_OS_MACX)
  CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
  CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef, kCFURLPOSIXPathStyle);
  MATERIAL_DIR = QString( CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding())) + "/Contents/Resources";

  //Windows
  #elif defined(Q_OS_WIN)
  MATERIAL_DIR = a.applicationDirPath();
  
  //Linux/FreeBSD - material path may be passed in or assumed to be the local path
  #else
  if( argc > 1 )
  {
    //user is running program from installed location (e.g. /usr/local/bin)
    //in which case we must assume material files are installed in the defined location
    if( QString(argv[1]).contains(QString(BIN_DIR)) != 0 )
    { MATERIAL_DIR = DATA_DIR; }

    //if the above is not the case assume the user is running a non-installed copy of Album Shaper
    // (say right after compiling it, in which case the materials should be in the same location so
    //use application dir path directly
    else 
    { MATERIAL_DIR = QString(argv[1]); }
  }
  //if the binary is run directly assume we're in the same directory as it and use the
  //current directory to load materials from
  else
    MATERIAL_DIR = "./";
  #endif

  //----------------------------------------------
  //set image path
  IMAGE_PATH = MATERIAL_DIR + "/images/";
  //----------------------------------------------
  //set handbook path, attempt to use locale specific directory, otherwise fall back on english default
  HANDBOOK_PATH = MATERIAL_DIR + "/handbook_" + QTextCodec::locale() + "/";
  QDir handbookDir( HANDBOOK_PATH );
  if(!handbookDir.exists())
    HANDBOOK_PATH = MATERIAL_DIR + "/handbook/";
  //----------------------------------------------
  //set text path, attempt to use locale specific directory, otherwise fall back on english default
  TEXT_PATH = MATERIAL_DIR + "/text_" + QTextCodec::locale() + "/";
  QDir textDir( TEXT_PATH );
  if(!textDir.exists())
    TEXT_PATH = MATERIAL_DIR + "/text/";
  //----------------------------------------------
  //set themes path
  THEMES_PATH = MATERIAL_DIR + "/themes/";
  //----------------------------------------------
  //set xml conversion path
  XMLCONVERSION_PATH = MATERIAL_DIR + "/xmlConversion/";
  //----------------------------------------------
  //check that directory where user settings is stored exists, if not create
  //that directory at this time.
  if( !Configuration::constructSettingsDirectory() )
  {
    std::cout << "Error! Unable to make configurations directory!\n";
    return -1;
  }
  //----------------------------------------------
  //where temporary files can be placed

  //PLATFORM_SPECIFIC_CODE
  
  bool tempDirMade = true;
  QDir homeDir;
  
  //Mac OS X
  #if defined(Q_OS_MACX)
  homeDir = QDir::homeDirPath();
  homeDir.cd("Library");
  homeDir.cd("Application Support");
  if(!homeDir.exists("Album Shaper"))
  { tempDirMade = homeDir.mkdir("Album Shaper"); }
  TEMP_DIR = QDir::convertSeparators( QDir::homeDirPath() + QString("/Library/Application Support/Album Shaper") );

  //Windows
  #elif defined(Q_OS_WIN)
  QString folderLoc;
  if( !getWindowsFolderLocation(APPLICATION_DATA,  folderLoc) )
  { 
    std::cout << "Error! Unable to identify Application Data folder!\n";
    return -1;
  }

  QDir applicationDataDir( folderLoc );
  if(!applicationDataDir.exists("Album Shaper"))
  { tempDirMade = applicationDataDir.mkdir("Album Shaper"); }
  TEMP_DIR = QDir::convertSeparators ( folderLoc + QString("/Album Shaper") );

  //Unix/Linux/BSD
  #else
  homeDir = QDir::homeDirPath();
  if(!homeDir.exists(".albumShaper")) { tempDirMade = homeDir.mkdir(".albumShaper"); }
  TEMP_DIR = QDir::homeDirPath() + QString("/.albumShaper");
  #endif

  //if unable to make configuration directory then abort
  if(!tempDirMade)
  {
    std::cout << "Error! Unable to make temp files directory!\n";
    return -1;
  }
  //----------------------------------------------
  //create translator for current locale and attempt to install
  QTranslator translator( 0 );
  translator.load( QString("AlbumShaper_") + 
//                   "sv",
                   QTextCodec::locale(), 
                   MATERIAL_DIR + "/translations");

  a.installTranslator( &translator );

  //create main window and show
  Window window;
  a.setMainWidget( &window );
  //----------------------------------------------
  //set window size and position
  Configuration* config = window.getConfig();
  if( config->getBool( "layout", "restoreWindowPlacementSize") )
  {
    window.resize( config->getInt( "layout", "windowWidth" ),
                             config->getInt( "layout", "windowHeight" ) );

    window.move( config->getInt( "layout", "windowPosX" ),
                             config->getInt( "layout", "windowPosY" ) );
  }
  else
  {
     QDesktopWidget *desktop = QApplication::desktop();
     int size = config->getInt( "layout", "defaultWindowSize" );
     int placement = config->getInt( "layout", "defaultWindowPlacement" );

     QRect availRect = desktop->availableGeometry();
     int width = (size*availRect.width()) / 100;
     int height = (size*availRect.height()) / 100;

    window.resize( width, height );
    width = window.frameGeometry().width();
    height = window.frameGeometry().height();

     int x, y;
     //top left
     if(placement == TOP_LEFT)
     {
       x = availRect.left();
       y = availRect.top();
     }
     //top right
     else if(placement == TOP_RIGHT)
     {
       x = availRect.right() - width;
       y = availRect.top();
     }
     //bottom left
     else if(placement == BOTTOM_LEFT)
     {
       x = availRect.left();
       y = availRect.bottom() - height;
     }
     //bottom right
     else if(placement == BOTTOM_RIGHT)
     {
       x = availRect.right() - width;
       y = availRect.bottom() - height;
     }
     //center
     else
     {
       x = availRect.left() + (availRect.width() - width) / 2;
       y = availRect.top() + (availRect.height() - height) / 2;
     }

     //place window
     window.move( x, y );
  }
  window.show();

  //load cursors
  loadCursors();
  
  //-----------------------------------
  //if this is a CVS build and cvsWarn set warn
  //user that application is potentially unstable!
  #ifdef CVS_CODE
  if( config->getBool ( "misc", "cvsWarn" ) )
  {
    AlertDialog alert( "Warning! Unstable build!", 
                       QString("Warning! You are running a potentially unstable (CVS) build of Album Shaper! It is strongly suggested you only use this copy for testing and evaluation purposes. Data loss may occur!"),
                       "alertIcons/warning.png", &window );
    alert.exec();    
  }
  #endif
  //-----------------------------------
  //if this is the first time the program is being run then show welcome screen
  WelcomeWindow* welcome;
  if(config->getBool( "misc", "firstRun" ) )
  {
    welcome = new WelcomeWindow();
    welcome->show();
    centerWindow(welcome);
    config->setBool( "misc", "firstRun", false );
  }
  //-----------------------------------
  return a.exec();
}
