/***************************************************************************
                          c6search.cpp  -  description
                             -------------------
    begin                : Fri Nov 7 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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "c6search.h"
#include <qwidget.h>

#include <qcombobox.h>
#include <qrect.h>
#include <qdir.h>
#include <qstringlist.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qlineedit.h>
#include <qmessagebox.h>
#include <qpixmap.h>
#include <qapplication.h>
#include <qlistview.h>
#include <qfont.h>
#include <qpopupmenu.h>
#include <qcursor.h>
#include <qfile.h>
#include <qdatastream.h>
#include <qdir.h>
#include <qpushbutton.h>
#include <qptrlist.h>
#include <qlistbox.h>
#include <qcheckbox.h>
#include <qtooltip.h>
#include "c6button.h"
#include "c6pixmapcache.h"
#include "c6settings.h"
#include "c6global.h"
#include <qlayout.h>
#include <qstringlist.h>
#include <qheader.h>
#include "c6users.h"
#include "c6photoretriever.h"

enum SEARCH_STATE
{
    FREE_STATE=1,
    NETFRIEND_STATE=2,
    BUSY_STATE=4
};

#define DCOMBO 30
#define HCOMBO 18
#define WCOMBO 150
#define YCOMBO 130
#define MID (MAX_COMBO/2)

#define FOUND_USERS_STR "Utenti trovati: "
#define NOT_SELECTED_STR "----------------"

static const QString SEARCHWAITSTR = "Ricerca in corso...........";
static const QString C6SAVECOMBO  = "search.sav";
static const int PHOTO_ITEM_WIDTH = 32;
static const int PHOTO_ITEM_HEIGHT = 32;
static const int NICK_ITEM_WIDTH = 300;

static const char* textSearchString[]=
    {"Età","Genere","Sta cercando","Area Geografica","Regione/Provincia"};

static const char* comboItemsString[MAX_COMBO][130] = 
{
    {
        NOT_SELECTED_STR,
        "non definita",
        "meno di 14 anni",
        "da 14 a 18 anni",
        "da 19 a 27 anni",
        "da 28 a 35 anni",
        "da 36 a 45 anni",
        "da 45 a 65 anni",
        "da 65 a 85 anni",
        "da 85 a 130 anni",
        "da 130 a 200 anni",
        "da 200 a 500 anni",
        "oltre i 500 anni",
        0      
    },
    {
        NOT_SELECTED_STR,
        "non definito",
        "maschile",
        "femminile",
        0      
    },
    {
        NOT_SELECTED_STR,
        "non definito",
        "uomo",
        "donna",
        0       
    },
    {
        NOT_SELECTED_STR,      
        "non definita",
        "Italia",
        "Vaticano",
        "rep. di S.Marino",
        "Europa",
        "Africa",
        "America del nord",
        "America latina",
        "Asia",
        "Australia e Nuova Zelanda",
        0
    },
    {
        NOT_SELECTED_STR,
        "non definita",
        "Abruzzo",
        "Basilicata",
        "Calabria",
        "Campania",
        "Emilia Romagna",
        "Friuli-Venezia Giulia",
        "Lazio",
        "Liguria",
        "Lombardia",
        "Marche",
        "Molise",
        "Piemonte",
        "Puglia",
        "Sardegna",
        "Sicilia",
        "Toscana",
        "Trentino-Alto Adige",
        "Umbria",
        "Valle d'Aosta",
        "Veneto",
        "----------",      
        "Agrigento",
        "Alessandria",
        "Ancona",
        "Aosta",
        "Arezzo",
        "Ascoli Piceno",
        "Asti",
        "Avellino",
        "Bari",
        "Belluno",
        "Benevento",
        "Bergamo",
        "Biella",
        "Bologna",
        "Bolzano",
        "Brescia",
        "Brindisi",
        "Cagliari",
        "Caltanissetta",
        "Campobasso",
        "Caserta",
        "Catania",
        "Catanzaro",
        "Chieti",
        "Como",
        "Cosenza",
        "Cremona",
        "Crotone",
        "Cuneo",
        "Enna",
        "Ferrara",
        "Firenze",
        "Foggia",
        "Forli'",
        "Frosinone",
        "Genova",
        "Gorizia",
        "Grosseto",
        "Imperia",
        "Isernia",
        "L'Aquila",
        "La Spezia",
        "Latina",
        "Lecce",
        "Lecco",
        "Livorno",
        "Lodi",
        "Lucca",
        "Macerata",
        "Mantova",
        "Massa Carrara",
        "Matera",
        "Messina",
        "Milano",
        "Modena",
        "Napoli",
        "Novara",
        "Nuoro",
        "Oristano",
        "Padova",
        "Palermo",
        "Parma",
        "Pavia",
        "Perugia",
        "Pesaro",
        "Pescara",
        "Piacenza",
        "Pisa",
        "Pistoia",
        "Pordenone",
        "Potenza",
        "Prato",
        "Ragusa",
        "Ravenna",
        "Reggio Calabria",
        "Reggio Emilia",
        "Rieti",
        "Rimini",
        "Roma",
        "Rovigo",
        "Salerno",
        "Sassari",
        "Savona",
        "Siena",
        "Siracusa",
        "Sondrio",
        "Taranto",
        "Teramo",
        "Terni",
        "Torino",
        "Trapani",
        "Trento",
        "Treviso",
        "Trieste",
        "Udine",
        "Varese",
        "Venezia",
        "Verbania",
        "Vercelli",
        "Verona",
        "Vibo Valentia",
        "Vicenza",
        "Viterbo",
        0            
    }   
};

C6Search::C6Search(QWidget *parent, const char *name ) : search(parent,name)
{
    C6PixmapCache &pix = C6PixmapCache::getInstance();
    C6Global &global = C6Global::getInstance();
    QString path = global.getSkinPath();

    searchKey[0] = combo0;
    label0->setText(QString::fromUtf8(textSearchString[0]));
    searchKey[1] = combo1;
    label1->setText(QString::fromUtf8(textSearchString[1]));
    searchKey[2] = combo2;
    label2->setText(QString::fromUtf8(textSearchString[2]));
    searchKey[3] = combo3;
    label3->setText(QString::fromUtf8(textSearchString[3]));
    searchKey[4] = combo4;
    label4->setText(QString::fromUtf8(textSearchString[4]));

    for (int i=0; i < MAXCOMBO; i++)
    {
        searchKey[i]->insertStrList(comboItemsString[i]);
    }          
    
    exitButtonPlaceHolder->hide();
    C6Button *closeButton = new C6Button(frame15,0,0,path+"chat_71.png",path+"chat_over_109.png");
    layout22->addWidget(closeButton);
    connect(closeButton,SIGNAL(clicked()),this,SLOT(close()));

    searchButtonPlaceHolder->hide();
    C6Button *searchButton = new C6Button(frame24,0,0,path+"cerca_10.png",path+"cerca_over_10.png",
                                          QString::null,Qt::ThresholdDither);
    layout120->addWidget(searchButton);
    connect(searchButton,SIGNAL(clicked()),SLOT(startSearch()));

    saveButtonPlaceHolder->hide();
    C6Button *saveButton = new C6Button(frame24,0,0,path+"salva_06.png",path+"salva_06_over.png");
    layout49->addWidget(saveButton);
    connect(saveButton,SIGNAL(clicked()),SLOT(saveClicked()));
    connect(searchSave,SIGNAL(activated(int)),SLOT(selectValue(int)));
    connect(profileSwitch,SIGNAL(clicked()),SLOT(selectProfile()));
    connect(emailSwitch,SIGNAL(clicked()),SLOT(selectEmail()));
    connect(searchKey[3],SIGNAL(activated(const QString&)),SLOT(checkCountry(const QString&)));
    connect(nickSwitch,SIGNAL(clicked()),SLOT(selectNick()));
    
    
    QWidget *upParent = reinterpret_cast<QWidget*>(aboutButtonPlaceHolder->parent());
    C6Button* aboutButton = new C6Button(upParent,0,0,path+"chat_68.png",
                                         path+"chat_over_68.png",
                                         path+"chat_over_68.png");
    QToolTip::add
            (aboutButton,"Informazioni su OpenC6");
    aboutButtonPlaceHolder->hide();
    layout23->addWidget(aboutButton);   
    connect(aboutButton,SIGNAL(clicked()),this,SLOT(aboutClicked()));   
    
    menu = new QPopupMenu(this);
    subMenu = new QPopupMenu(menu);
    
    menu->insertItem(QIconSet(pix.getPixmap(path+"login-photo.png")),"Profilo ridotto",ALLPROFILE);
    menu->insertItem(QIconSet(pix.getPixmap(path+"filetypes.png")),"Inizia Chat",INITCHAT);
    menu->insertItem(QIconSet(pix.getPixmap(path+"edit_add.png")),"Aggiungi a",subMenu);
    menu->insertItem(QIconSet(pix.getPixmap(path+"login-photo.png")),"Profilo Completo",PROFILE);
    connect(onlinePeople,SIGNAL(rightButtonClicked(QListViewItem *, const QPoint &, int )),
            this,SLOT(menuClicked(QListViewItem *, const QPoint &, int )));
    connect(onlinePeople,SIGNAL(doubleClicked(QListViewItem *,const QPoint &, int)),this,SLOT(doubleClicked(QListViewItem *,const QPoint &, int)));

    selectProfile();
    loadDefaultSearch();
    notInListFilter->setChecked(false);
    
    onlinePeople->header()->hide();    
    onlinePeople->clear();
    onlinePeople->setColumnWidthMode(0,QListView::Manual);       
    onlinePeople->setColumnWidthMode(1,QListView::Manual);      
    onlinePeople->setColumnWidth(1,PHOTO_ITEM_WIDTH);
    
    foundUsers->setText(FOUND_USERS_STR+QString::number(0));
    global.setBehaviourIfMacOSX(onlinePeople);   
    
    _photoRetriever = new C6PhotoRetriever();    
    connect(_photoRetriever,SIGNAL(photoReady(QByteArray&,const QString&)),
            SLOT(setPhoto(QByteArray&,const QString&)));      
}

C6Search::~C6Search()
{
    delete menu;
    delete subMenu;
    delete _photoRetriever;    
}

void C6Search::startSearch()
{
    unsigned char choice[255];      
    
    if (profileSwitch->isChecked())
    {
        int valueNo=0;    
        int index = 1;    
        
        for (int i=0; i < MAXCOMBO; i++)
        {
            if (searchKey[i]->currentText().compare(NOT_SELECTED_STR) != 0)
            {                
                int current = searchKey[i]->currentItem();         
                int comboNo = 0;
                
                if (i < 3)
                {               
                    comboNo = i+1;    
                }               
                else
                {
                    comboNo = i+2;    
                }               
                    
                choice[index] = comboNo;
                choice[index+1] = current;
                index+=2;
                valueNo++;    
            }         
        }

        if (onlyPhoto->isChecked() == true)
        {
            choice[index] = 0x0e;     
            choice[index+1] = 1;   
            valueNo++;
        }             
        
        if (valueNo >= 0)
        {
            choice[0] = valueNo;
            setWaitResult();         
            emit sendSearchValue(choice,C6Proto::PROFILE_SEARCH);
        }
    }
    else
    {
        if (emailSwitch->isChecked() == true)
        {             
            QString email = emailEdit->displayText().stripWhiteSpace();    
            int len = email.length();
            if (len > 0)
            {
                choice[0] = len;
                memcpy(&choice[1],email.latin1(),len);
                setWaitResult();            
                emit sendSearchValue(choice,C6Proto::EMAIL_SEARCH);
            }         
            else
            {
                qApp->beep();
                QMessageBox::warning(this,"Errore","Nessuna email specificata !",QMessageBox::Ok,QMessageBox::NoButton);
            }
        }
        else
        {
            QString nick = nickEdit->displayText().stripWhiteSpace();
            setWaitResult();             
            emit searchByNick(nick);        
        }            
    }
}

void C6Search::selectProfile()
{
    profileSwitch->setChecked(true);
    emailSwitch->setChecked(false);
    nickSwitch->setChecked(false);   
    emailEdit->setEnabled(false);
    nickEdit->setEnabled(false);   
    searchSave->setEnabled(true);  
    onlyPhoto->setEnabled(true);     

    for (int i=0; i < MAXCOMBO; i++)
    {
        if ((i == 4) && (searchKey[i-1]->currentItem() < 2))
        {
            searchKey[i]->setEnabled(false);
        }
        else
        {         
            searchKey[i]->setEnabled(true);
        }         
    }

}

void C6Search::selectEmail()
{
    profileSwitch->setChecked(false);
    emailSwitch->setChecked(true);
    emailEdit->setEnabled(true);
    nickSwitch->setChecked(false);  
    nickEdit->setEnabled(false);
    emailEdit->setFocus();        
    searchSave->setEnabled(false);   
    onlyPhoto->setEnabled(false);        

    for (int i=0; i < MAXCOMBO; i++)
    {      
        searchKey[i]->setEnabled(false);
    }      
}

void C6Search::selectNick()
{
    profileSwitch->setChecked(false);
    emailSwitch->setChecked(false);
    emailEdit->setEnabled(false);
    nickEdit->setEnabled(true);
    nickEdit->setFocus();   
    searchSave->setEnabled(false);         
    onlyPhoto->setEnabled(false);     
    
    for (int i=0; i < MAXCOMBO; i++)
    {      
        searchKey[i]->setEnabled(false);
    }      
}

void C6Search::showResults(QStringList *nicklst,std::vector<C6Users::C6USER_STATUS> statuslst)
{
    bool found=false;
    C6PixmapCache &pix = C6PixmapCache::getInstance();
    C6Global &global = C6Global::getInstance();
    QString path = global.getSkinPath();
    QStringList netfriendList = C6Global::getInstance().getAllUsers();    
    
    const QPixmap &flagIcon = pix.getPixmap(path+"flag.png");
    const QPixmap &greenBall = pix.getPixmap(path+"Contact_green.png");
    const QPixmap &redBall = pix.getPixmap(path+"Contact_busters.png");
    const QPixmap &yellowBall = pix.getPixmap(path+"Contact_block.png");
    const QPixmap &whiteBall = pix.getPixmap(path+"Contact_away.png");    
    const QPixmap &noPhoto = pix.getPixmap(path+"nophoto32x32.png");    
    
    onlinePeople->clear();

    if (nicklst->count())
    {
        int i = 0;    
        QListViewItem *previous = 0;    
        for (QStringList::Iterator it = nicklst->begin(); it != nicklst->end(); ++it)
        {
            found = false;
            if (notInListFilter->isChecked())
            {
                for (unsigned int k=0; k < netfriendList.count(); k++)    
                {
                    if (netfriendList[k].compare(*it) == 0)     
                    {                  
                        found = true;
                        break;
                    }
                }
            }

            if (!found)
            {
                switch(statuslst[i])
                {
                    case C6Users::U_BUSY:
                        if (onlyAvailable->isChecked() == false)
                        {                        
                            previous = new QListViewItem(onlinePeople,previous,*it);
                            previous->setPixmap(0,redBall);   
                                                 
                        }                     
                        break;
                    case C6Users::U_NETFRIENDONLY:
                        if (onlyAvailable->isChecked() == false)
                        {                     
                            previous = new QListViewItem(onlinePeople,previous,*it);
                            previous->setPixmap(0,yellowBall);     
                                                                   
                        }                     
                        break;
                    case C6Users::U_AVAILABLE:
                        previous = new QListViewItem(onlinePeople,previous,*it);
                        previous->setPixmap(0,greenBall);                                                           
                        break;                                
                    case C6Users::U_AWAY:
                        if (onlyAvailable->isChecked() == false)
                        {                                       
                            previous = new QListViewItem(onlinePeople,previous,*it);
                            previous->setPixmap(0,whiteBall);    
                        }                     
                        break;
                    default:   
                        previous = new QListViewItem(onlinePeople,previous,*it);
                        previous->setPixmap(0,greenBall);                                           
                        qWarning("unknown state %s %x \n",(*it).latin1(),statuslst[i]);                                              
                }                   
                onlinePeople->setColumnWidth(0,onlinePeople->width()-
                        onlinePeople->verticalScrollBar()->width()-PHOTO_ITEM_WIDTH-5);       
                
                if (previous != 0)
                {                    
                    previous->setPixmap(1,noPhoto);        
                }               
            }
            i++;
        }
    }
   
    if (onlinePeople->childCount() == 0)
    {
        foundUsers->setText(FOUND_USERS_STR+QString::number(0));      
        QListViewItem* tmp = new QListViewItem(onlinePeople,0,NO_USER_FOUND_MSG);
        tmp->setPixmap(0,flagIcon);                  
    }
    else
    {
        foundUsers->setText(FOUND_USERS_STR+QString::number(onlinePeople->childCount()));  
    }    
   
    QApplication::postEvent(_photoRetriever,new PhotoListEvent(*nicklst));
    if (onlinePeople->firstChild() != 0)
    {         
        onlinePeople->setCurrentItem(onlinePeople->firstChild());    
    }      
}

void C6Search::checkCountry(const QString &a)
{
    if (searchKey[3]->currentItem() > 1)
    {      
        searchKey[4]->setEnabled(true);
    }      
    else
    {
        searchKey[4]->setEnabled(false);
        searchKey[4]->setCurrentItem(0);
    }
}

void C6Search::menuClicked(QListViewItem* item, const QPoint &pos, int )
{
    if (onlinePeople->childCount())
    {
        if (!((onlinePeople->childCount() == 1) &&
               ((onlinePeople->firstChild()->text(0).compare(NO_USER_FOUND_MSG) == 0) ||
               (onlinePeople->firstChild()->text(0).compare(SEARCHWAITSTR)) == 0)))
        {
            C6Global &global = C6Global::getInstance();
            C6PixmapCache &pix = C6PixmapCache::getInstance();
            QString path = global.getSkinPath();         
            QStringList groups = C6Global::getInstance().getAllGroups();
            
            subMenu->clear();
            
            for(unsigned int i=0; i < groups.count(); i++)   
            {      
                subMenu->insertItem(pix.getPixmap(path+"group_folder.png"),groups[i],i+MOVE);
            }    
            
            int ret = menu->exec(QCursor::pos());
            if (ret != -1)
            {
                emit searchMenuClicked(item->text(0),static_cast<USER_MENU_ACTIONS>(ret));
            }
        }
    }
}

void C6Search::loadDefaultSearch()
{
    QString home = QDir::homeDirPath();
    QFile file( home+"/"+C6DIR+"/"+C6SAVECOMBO);
    QDataStream stream( &file );

    if (file.open( IO_ReadOnly))
    {
        for (int i =0; i < SAVESLOT; i++)
        {         
            stream.readRawBytes((char*)&searchSavedValue[i],MAXCOMBO);
        }         

        file.close();
    }
    else
    {      
        for (int i=0; i < SAVESLOT; i++)
        {         
            memset(&searchSavedValue[i],0,MAXCOMBO);
        }         
    }      
}

void C6Search::saveDefaultSearch()
{
    QString home = QDir::homeDirPath();
    QFile file( home+"/"+C6DIR+"/"+C6SAVECOMBO);
    QDataStream stream( &file );

    if (file.open(IO_WriteOnly | IO_Raw))
    {
        for (int j=0; j < SAVESLOT; j++)
        {         
            stream.writeRawBytes((char*)&searchSavedValue[j],MAXCOMBO);
        }         

        file.close();
    }
}

void C6Search::saveClicked()
{
    int x = searchSave->currentItem();

    if (x > 0)
    {
        for (int i=0; i < MAXCOMBO; i++)
        {         
            searchSavedValue[x-1][i]= searchKey[i]->currentItem();
        }         

        saveDefaultSearch();
    }

}

void C6Search::selectValue(int sel)
{
    QString dummy;

    if (sel)
    {
        for (int i=0; i < MAXCOMBO; i++)
            searchKey[i]->setCurrentItem(searchSavedValue[sel-1][i]);

        checkCountry(dummy);
    }
}


/*!
    \fn C6Search::doubleClicked(QListViewItem *,const QPoint &, int)
 */
void C6Search::doubleClicked(QListViewItem *item,const QPoint &point, int)
{
    if (item != 0)
    {
        if ((item->text(0).compare(NO_USER_FOUND_MSG) != 0) && (item->text(0).compare(SEARCHWAITSTR) != 0))
        {
            emit searchMenuClicked(item->text(0),INITCHAT);
        }
    }
}

/*!
    \fn C6Search::setCustomFont()
 */
void C6Search::setCustomFont()
{
    C6Global &global=C6Global::getInstance();      
    QFont lfont(global.getBaseFont());
    
    int size = lfont.pointSize()-1;
    
    if (size > 2)
    {
        lfont.setPointSize(size);
        setFont(lfont);      
    }
}

void C6Search::aboutClicked()
{
    emit showAbout();
}

void C6Search::setWaitResult()
{
    C6PixmapCache &pix = C6PixmapCache::getInstance();
    C6Global &global = C6Global::getInstance();
    QString path = global.getSkinPath();
    
    QPixmap& waitSearch = const_cast<QPixmap&>(pix.getPixmap(path+"hotsync_busy.png"));   
    onlinePeople->clear();
    QListViewItem* tmp = new QListViewItem(onlinePeople,0,SEARCHWAITSTR);
    tmp->setPixmap(0,waitSearch);        
    foundUsers->setText(FOUND_USERS_STR+QString::number(0));
}      


/*!
    \fn C6Search::setPhoto(QByteArray& data,const QString& filename)
 */
void C6Search::setPhoto(QByteArray& data,const QString& filename)
{
    QString tmp = filename;
    int commaIndex = filename.find(',');        
   
    if (commaIndex != -1)
    {          
        QListViewItemIterator it(onlinePeople);
    
        for ( ; it.current(); ++it )
        {      
            if (it.current()->text(0).compare(filename.left(commaIndex)) == 0)
            {          
                QPixmap photo(data);         
                it.current()->setPixmap(1,photo);         
                break;    
            }         
        }   
    }
}
