/***************************************************************************
 *   Copyright (C) 2007 by Anistratov Oleg                                 *
 *   ower@users.sourceforge.net                                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation;                         *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 ***************************************************************************/

#include "smileswgt.h"
#include "globals.h"

#include <math.h>
#include <assert.h>

#include <QPixmap>
#include <QPainter>
#include <QDir>
#include <QFile>
#include <QIcon>

#include <QMovie>

#include <QDomElement>
#include <QDomDocument>
#include <QDomNodeList>

#include "smilelabel.h"
#include "qchaticon.h"

SmilesWgt::SmilesWgt(QWidget *parent) :
  QWidget(parent),
  m_inited(false),
  m_smilesNum(0),
  m_smilesMaxNum(100)
{
//   QScrollArea* scrll = new QScrollArea(parentWidget());
  m_grid   = new QGridLayout(this);

  m_smiles = (SmileLabel**)malloc(m_smilesMaxNum * sizeof(SmileLabel*));
  Q_ASSERT(NULL != m_smiles);

  m_grid->setMargin(1);
  m_grid->setSpacing(1);

  setMouseTracking(true);

//   resize(600, 400);

//   scrll->setWidget(this);
// scrll->show();

  setWindowIcon(QChatIcon::icon("emotes"));
}

SmilesWgt::~SmilesWgt()
{
}

void SmilesWgt::loadTheme(const QString & path)
{
  if(!QDir().exists(path))
    return;

  if(m_inited)
    clear();

  QFile file(path + "/emoticons.xml");
  QDomDocument dom_document;
  QDomElement  root;
  QDomElement  child;
  QDomElement  emoticon;
  QDomElement  name;
  QDomNodeList elements;
  QDomNodeList elements_names;
  QStringList  list;

  if(!file.open(QIODevice::ReadOnly))
  {
    Globals::addError("Couldn't open " + path + "/emoticons.xml");
    return;
  }

  if(!dom_document.setContent(&file, true))
  {
    Globals::addError("Couldn't parse " + path + "/emoticons.xml");
    return;
  }

  root     = dom_document.documentElement();
  elements = root.elementsByTagName("emoticon");

  for(uint i = 0, len = elements.length(); i < len; i++)
  {
    emoticon       = elements.item(i).toElement();
    elements_names = emoticon.elementsByTagName("string");

    list.clear();

    for(uint j = 0, len = elements_names.length(); j < len; j++)
    {
      child = elements_names.item(j).toElement();
      list.append(child.text());
    }

    addSmile(emoticon.attribute("file"), list, path);
  }

  int cols   = (int)sqrt(m_smilesNum);
  for(int i = 0; i < m_smilesNum; i++)
    m_grid->addWidget(m_smiles[i], i / cols, i % cols);

  m_inited = true;
}

void SmilesWgt::addSmile(const QString & fname, const QStringList & list, const QString & dir)
{
  if(m_smilesMaxNum <= ++m_smilesNum)
  {
    m_smilesMaxNum += 10;
    m_smiles = (SmileLabel**)realloc(m_smiles, m_smilesMaxNum * sizeof(SmileLabel*));
    assert(NULL != m_smiles);
  }

  m_smiles[m_smilesNum - 1] = new SmileLabel(this);

  connect(m_smiles[m_smilesNum - 1], SIGNAL(clicked(const QString &)), this, SIGNAL(smileClicked(const QString &)));
  connect(m_smiles[m_smilesNum - 1], SIGNAL(clicked(const QString &)), this, SIGNAL(wantHide()));
  connect(m_smiles[m_smilesNum - 1], SIGNAL(hovered(               )), this, SLOT  (unselectAll()));

  m_smiles[m_smilesNum - 1]->setFilename(fname);
  m_smiles[m_smilesNum - 1]->setSmileText(list);
  m_smiles[m_smilesNum - 1]->load(dir);
}

void SmilesWgt::init()
{
  loadTheme(QChatSettings::settings()->smilesThemePath());
}

void SmilesWgt::clear()
{
  if(m_inited)
  {
    for(; m_smilesNum > 0; m_smilesNum--)
    {
      m_grid->removeWidget(m_smiles[m_smilesNum - 1]);
      delete m_smiles[m_smilesNum - 1];
    }

    m_inited = 0;
  }
}

void SmilesWgt::setOptimalSize()
{
  resize(optimalSize());
}

QSize SmilesWgt::optimalSize()
{
  int maxHe = 0, maxWd = 0;

  for(int i = 0; i < m_smilesNum; i++)
  {
    if(m_smiles[i]->pixmapWidth() > maxWd)
      maxWd = m_smiles[i]->pixmapWidth();

    if(m_smiles[i]->pixmapHeight() > maxHe)
      maxHe = m_smiles[i]->pixmapHeight();
  }

  int cols = (int)sqrt(m_smilesNum);
  int rows = (int)sqrt(m_smilesNum) + (m_smilesNum != cols * cols);

  return QSize(maxWd * cols, maxHe * rows);
}

void SmilesWgt::unselectAll()
{
  SmileLabel* lab = qobject_cast<SmileLabel*>(sender());

  for(int i = 0; i < m_smilesNum; i++)
  {
    if(m_smiles[i] != lab)
      m_smiles[i]->unselect();
  }
}
