/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
 *            collapser.cc
 *
 *  Mon Sep 15 09:48:46 CEST 2008
 *  Copyright 2008 Bent Bisballe Nyeng
 *  deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of Pracro.
 *
 *  Pracro 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.
 *
 *  Pracro 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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Pracro; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */
#include "collapser.h"
#include <QApplication>
#include <QHBoxLayout>

#define ANIM_TIME 100
#define ANIM_INTERVAL 20

Collapser::Collapser(QWidget *collapsed, QWidget *expanded, bool setcollapsed)
{
  this->collapsed = NULL;
  this->expanded = NULL;

  setLayout(new QHBoxLayout());
  layout()->setContentsMargins(0,0,0,0);

  setWidgets(collapsed, expanded);

  is_collapsed = !setcollapsed; // Make sure setCollapsed actually does something.
  setCollapsed(setcollapsed);
}

void Collapser::setWidgets(QWidget *collapsed, QWidget *expanded)
{
  setCollapsedWidget(collapsed);
  setExpandedWidget(expanded);
}

void Collapser::setCollapsedWidget(QWidget *collapsed)
{
  if(this->collapsed) {
    delete this->collapsed;
    this->collapsed = NULL;
  }

  this->collapsed = collapsed;

  if(isCollapsed() == true && collapsed) {
    layout()->addWidget(collapsed);
    collapsed->setVisible(true);
  }
}

void Collapser::setExpandedWidget(QWidget *expanded)
{
  if(this->expanded) {
    delete this->expanded;
    this->expanded = NULL;
  }

  this->expanded = expanded;

  if(isCollapsed() == false && expanded) {
    layout()->addWidget(expanded);
    expanded->setVisible(true);
  }
}

QWidget *Collapser::collapsedWidget()
{
  return collapsed;
}

QWidget *Collapser::expandedWidget()
{
  return expanded;
}


bool Collapser::isCollapsed()
{
  return is_collapsed;
}

void Collapser::setCollapsed(bool setcollapsed)
{
  if(this->is_collapsed == setcollapsed) return;

  if(setcollapsed) collapse();
  else expand();
}

void Collapser::collapse()
{
  t_anim.start();

  is_collapsed = true;
  killTimer(timer_id);
  timer_id = startTimer(ANIM_INTERVAL);
}

void Collapser::expand()
{
  t_anim.start();

  // show expanded
  if(collapsed) {
    collapsed->setVisible(false);
    qApp->processEvents(); // Make sure it is actualle invisble before removing it form the layout.
    layout()->removeWidget(collapsed);
  }
  if(expanded) {
    layout()->addWidget(expanded);
    expanded->setVisible(true);
  }
  
  is_collapsed = false;
  killTimer(timer_id);
  timer_id = startTimer(ANIM_INTERVAL);
}

void Collapser::toggleCollapse()
{
  if(!is_collapsed) collapse();
  else expand();
}

void Collapser::anim()
{
  int c_height = 16;
  int e_height = 16;
  if(collapsed) {
    QSize sz = collapsed->minimumSizeHint();
    c_height = sz.height();
  }

  if(expanded) {
    QSize sz = expanded->minimumSizeHint();
    e_height = sz.height();
  }
  
  killTimer(timer_id);

  double x = (double)(t_anim.elapsed()) / (double)ANIM_TIME;
  double y = 1;

  if(x < 1) {
    y = x * x * x;

    int height;
    if(!is_collapsed) {
      height = (int)((1 - y) * c_height + y * e_height);
    } else {
      height = (int)((1 - y) * e_height + y * c_height);
    }
    setFixedHeight(height);

    timer_id = startTimer(ANIM_INTERVAL);
  } else {

    if(is_collapsed) {
      // show collapsed
      if(expanded) {
        expanded->setVisible(false);
        qApp->processEvents(); // Make sure it is actualle invisble before removing it form the layout.
        layout()->removeWidget(expanded);
      }
      if(collapsed) {
        layout()->addWidget(collapsed);
        collapsed->setVisible(true);
      }

      setFixedHeight(c_height);
    } else {
      setFixedHeight(e_height);
    }

  }
}

void Collapser::timerEvent(QTimerEvent *)
{
  anim();
}