/****************************************************************************
**
** Copyright (C) 2001-2006 Frank Hemer <frank@hemer.org>,
**                         Tilo Riemer <riemer@crossvc.com>
**
**
**----------------------------------------------------------------------------
**
**----------------------------------------------------------------------------
**
** CrossVC is available under two different licenses:
**
** If CrossVC is linked against the GPLed version of Qt 
** CrossVC is released under the terms of GPL also.
**
** If CrossVC is linked against a nonGPLed version of Qt 
** CrossVC is released under the terms of the 
** CrossVC License for non-Unix platforms (CLNU)
**
**
** CrossVC License for non-Unix platforms (CLNU):
**
** Redistribution and use in binary form, without modification, 
** are permitted provided that the following conditions are met:
**
** 1. Redistributions in binary form must reproduce the above copyright
**    notice, this list of conditions and the following disclaimer in the
**    documentation and/or other materials provided with the distribution.
** 2. It is not permitted to distribute the binary package under a name
**    different than CrossVC.
** 3. The name of the authors may not be used to endorse or promote
**    products derived from this software without specific prior written
**    permission.
** 4. The source code is the creative property of the authors.
**    Extensions and development under the terms of the Gnu Public License
**    are limited to the Unix platform. Any distribution or compilation of 
**    the source code against libraries licensed other than gpl requires 
**    the written permission of the authors.
**
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
**
**
** CrossVC License for Unix platforms:
**
** 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, version 2 of the License.
** 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 version 2 for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*****************************************************************************/

#include "config.h"


#include "MenuItem.h"

// This class should be defined MenuItem::private, but some older compilers (gcc<3.x) can't handle it
template<class type> class ItemVector : public QPtrVector<type> {

public:
  ItemVector() {}
  ItemVector(unsigned int size) : QPtrVector<type>(size) {}
  ~ItemVector() {}
  //compare for m_menu && m_text
  //if no difference and m_menu==0, compare m_instanceNum
  virtual int compareItems( QPtrCollection::Item d1, QPtrCollection::Item d2 ) {
    int retVal = ((MenuItem*)d1)->caption().compare(((MenuItem*)d2)->caption());
    if (retVal == 0) {
      retVal = ((MenuItem*)d1)->menu() - ((MenuItem*)d2)->menu();
      if (retVal == 0) {
        return ((MenuItem*)d1)->getInstanceNum() - ((MenuItem*)d2)->getInstanceNum();
      } else {
        return retVal;
      }
    } else {
      return retVal;
    }
  }
};

// ---------------------------------------------------------------------------------------------

unsigned int MenuItem::m_instance=0;

QPtrVector<MenuItem> * MenuItem::instP = new ItemVector<MenuItem> (0);

MenuItem::MenuItem( int menu, const QIconSet &icon, const QString text, const char *member, int accel, int id, int count, int index)
  : m_icon(icon),m_text(text),m_member(member),m_accel(accel),
    m_id(id),m_count(count),m_index(index),m_menu(menu),
    m_enabled(TRUE),m_parent(NULL),m_isAutoAdd(FALSE)
{
  init();
}

MenuItem::MenuItem( int menu, const QString text, const char *member, int accel, int id, int count, int index)
    : m_icon(NULL),m_text(text),m_member(member),m_accel(accel),
      m_id(id),m_count(count),m_index(index),m_menu(menu),
      m_enabled(TRUE),m_parent(NULL),m_isAutoAdd(FALSE)
{
   init();
}

MenuItem::MenuItem( int menu, const QString text, int count)
  : m_icon(NULL),m_text(text),m_member(NULL),m_accel(0),
    m_id(-1),m_count(count),m_index(-1),m_menu(menu),
    m_enabled(TRUE),m_parent(NULL),m_isAutoAdd(FALSE)
{
  init();
}

MenuItem::~MenuItem() {}

void MenuItem::init() {
  m_childs = new ItemVector<MenuItem> (0);
  m_instanceNum=m_instance++;
  if (instP->count()<m_instance) instP->resize(m_instance);
  instP->insert((m_instance-1),this);
  ((ItemVector<MenuItem>*)instP)->sort();
}

int MenuItem::insertInto(QPopupMenu * menu, const QObject * receiver) const {
  return menu->insertItem(m_icon,m_text,receiver,m_member,m_accel,m_id,m_index);
}

void MenuItem::setAccel(const MenuItem * item, int val) {
  MenuItem * m = getInstance(item->getInstanceNum());
  if (m) {
    m->m_accel = val;
  }
}

void MenuItem::setParent(MenuItem * parent) {
  if (m_parent) qDebug("Error: MenuItem["+QString::number(m_instanceNum)+"]::parent reassigned");
  m_parent = parent;
  if ( !(m_parent->m_isAutoAdd) ) {
    m_isAutoAdd = TRUE;
    m_parent->addChild(this);
    m_isAutoAdd = FALSE;
  }
}

void MenuItem::addChild(MenuItem * item) {
  if (m_member) qDebug("Error: MenuItem["+QString::number(m_instanceNum)+"]::addChild declared as parent but SLOT defined");
  int pos = m_childs->count();
  m_childs->resize(pos+1);
  m_childs->insert(pos,item);
  m_childs->sort();
  if ( !(item->m_isAutoAdd) ) {
    m_isAutoAdd = TRUE;
    item->setParent(this);
    m_isAutoAdd = FALSE;
  }
}

MenuItem * MenuItem::getFirstChild() {
  if (m_childs->count() == 0) {
    return NULL;
  } else {
    m_childP = 0;
    return m_childs->at(m_childP);
  }
}

MenuItem * MenuItem::getNextChild() {
   ++m_childP;
   if (m_childs->count()==m_childP) {
      return NULL;
   } else {
      return m_childs->at(m_childP);
   }
}

MenuItem * MenuItem::nextSortedItem()const {
   if (this == lastSorted()) return NULL;
   int pos = ((ItemVector<MenuItem>*)instP)->bsearch(this);
   if (pos >= 0) {
      MenuItem * tmp = instP->at(pos+1);
      if (this == tmp) qDebug("Type: "+QString::number(tmp->menu())+" seems to have duplicate MenuItems: "+tmp->caption());
      return tmp;
   } else {
      return NULL;
   }
}

MenuItem * MenuItem::getInstance( int i_Num) {
   int i;
   for (i = 0; i < (int)(instP->count()); i++) {
      MenuItem *mi;
      if ( (mi = instP->at(i)) ) {
         if ((int)(mi->m_instanceNum) == i_Num) return mi;
      }
   }
   return NULL;
}

