/***************************************************************************
                          main.cpp  -  description
                             -------------------
    begin                : Fri Feb 14 16:20:30 CET 2003
    copyright            : (C) 2003 by Giorgio A.
    email                : openc6@hotmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <qfile.h>
#include <qdir.h>
#include "c6abstractplugin.h"
#include <qapplication.h>
#include <qptrvector.h>
#include <qsplashscreen.h>
#include "c6global.h"
#include "c6.h"

#define PIDFILE "OpenC6.pid"

static QSplashScreen *splash = 0;
static bool firstBoot = false;
static bool findExecPath(char *,char *);
static void checkIfRunning();
static void init();
static void showSplashScreen(QByteArray const & pixArray);
static void hideSplashScreen(QWidget *main);

int main(int argc, char *argv[])
{
    char share_path[255];
    QString commonPath;

    init();                                                   // create config directories
    checkIfRunning();
   
    if (findExecPath(argv[0],share_path))
    {      
        commonPath = QString(share_path);
    }      
    else
    {      
        commonPath =  "..";
    }      

    C6Global &global =  C6Global::getInstance(); 
    global.setCommonPath(commonPath);
    global.setFirstBoot(firstBoot);    
    global.loadPluginList();   
    
    QFile pixmapData(global.getSkinPath()+"splash.png");
    pixmapData.open(IO_ReadOnly);
    QByteArray pixmapArray = pixmapData.readAll(); 
    pixmapData.close();
       
    QStringList pluginsName = global.getPlugins();    
    C6AbstractPlugin* plugin = 0;    
    QApplication *app=0;        
    std::vector<C6AbstractPlugin*> pluginPtr;    
    
    for (unsigned int i=0; i < pluginsName.count(); i++)
    {
       plugin = global.buildPlugin(pluginsName[i]); 
       if (plugin != 0)
       {   
            pluginPtr.push_back(plugin); 
       }
    }          
    
    app = global.getKappInstance(); 
    
    if (app == 0)
    {
        app = new QApplication(argc,argv,"OpenC6");     
    }                
    
   
    showSplashScreen(pixmapArray);
    
    C6 *c6 = C6::getInstance();
    for (unsigned int i=0; i < pluginPtr.size(); i++)
    {
        global.initPlugin(pluginPtr.at(i)); 
    }    
    
    QApplication::connect(c6,SIGNAL(exit_main()),app,SLOT(quit()));
    c6->setStartedApp();    
    
    hideSplashScreen(c6->getLoginWidget());   
    int ret = app->exec();

    QDir tmp(QDir::homeDirPath()+"/"+C6DIR+"/");
    tmp.remove(PIDFILE);

    qWarning("Removing lock file. Exiting..\n");

    return ret;
}

bool findExecPath(char *argv,char *out)
{
    char path[255];

    strcpy(path,"which ");
    strcat(path,argv);
    strcat(path," > ");
    strncat(path,QDir::homeDirPath().latin1(),QDir::homeDirPath().length()+1);
    strcat(path,"/");
    strncat(path,C6DIR.latin1(),C6DIR.length()+1);
    strcat(path,"/");
    strcat(path,"temp");

    // which execbin > temp

    if (system(path) == -1)
        return false;

    QFile file(QDir::homeDirPath()+"/"+C6DIR+"/temp");
    QTextStream stream( &file );
    QString line;

    if (file.exists())
    {
        file.open(IO_ReadOnly);
        line = stream.readLine();
        file.close();

        if (line.contains("which"))                              //bin doesnt exists
            return false;

        if ((line == "c6") || (line == "./c6"))
            return false;

        line.truncate(line.findRev('/',-1));
        line.truncate(line.findRev('/',-1));
    }
    else
        return false;

    strncpy(out,line.latin1(),line.length()+1);
    return(true);
}

/** various initializations */
void init()
{
    QString home = QDir::homeDirPath();
    QDir *curdir = new QDir(home);

    if (!curdir->exists(C6DIR))
    {      
        curdir->mkdir(C6DIR);
        firstBoot = true;    
    }      

    if (!curdir->exists(C6DIR+"/Log"))
        curdir->mkdir(C6DIR+"/Log");

    if (!curdir->exists(C6DIR+"/SysLog"))
        curdir->mkdir(C6DIR+"/SysLog");

    if (!curdir->exists(C6DIR+"/Users"))
        curdir->mkdir(C6DIR+"/Users");

    if (!curdir->exists(C6DIR+"/RoomLog"))
        curdir->mkdir(C6DIR+"/RoomLog");

    delete curdir;
}

void checkIfRunning()
{
    pid_t pid;   
    QFile file(QDir::homeDirPath()+"/"+C6DIR+"/"+PIDFILE);
    QDataStream stream( &file );
       
    if (file.exists())
    {
        file.open(IO_ReadOnly);
        stream.readRawBytes((char*)&pid,sizeof(pid_t));
        file.close();

        if (kill(pid, 0) == -1)
            qWarning("\nIgnoring current pid %d\n",pid);
        else
        {
            qWarning("\nError: OpenC6 is already running at pid %d",pid);
            qFatal("Kill process or remove "+ QDir::homeDirPath()+"/"+C6DIR+"/"+PIDFILE+"\n");
        }
    }

    pid = getpid();
    file.open(IO_WriteOnly | IO_Raw);
    stream.writeRawBytes((char*)&pid,sizeof(pid_t));
    file.close();
}      


void showSplashScreen(QByteArray const & pixArray)
{
    QPixmap splashPixmap(pixArray);   
    splash = new QSplashScreen(splashPixmap,QApplication::WStyle_StaysOnTop);
    splash->show();
}

void hideSplashScreen(QWidget *main)
{
    if (splash != 0)
    {         
        splash->finish(main);
        delete splash;
    }      
}
