//=============================================================================

#include "subWindow.h"

#include <math.h>


const interval interval::NEVER;
  
interval
interval::operator+( int frm ) const
{
  if ( frm<start_ ) return interval(frm,end_);
  if ( frm>end_ )   return interval(start_,frm);
  return *this;
}

interval &
interval::operator+=( int frm )
{
  if ( frm<start_ ) start_=frm;
  else if ( frm>end_ ) end_=frm;
  return *this;
}

subWindow::subWindow( int centerX, int centerY, int sizeX, int sizeY )
  : centerX_(centerX), centerY_(centerY), sizeX_(sizeX), sizeY_(sizeY)
{
}

subWindow::subWindow( const subWindow &src )
  : centerX_(src.centerX_), centerY_(src.centerY_),
    sizeX_(src.sizeX_), sizeY_(src.sizeY_)
{
}

subWindow &
subWindow::operator=( const subWindow &src )
{
  centerX_=src.centerX_;
  centerY_=src.centerY_;
  sizeX_=src.sizeX_;
  sizeY_=src.sizeY_;
  return *this;
}

bool
subWindow::overlaps( const subWindow &src ) const
{
  return ( (abs(centerX_-src.centerX_) < (sizeX_+src.sizeX_)/2) &&
	   (abs(centerY_-src.centerY_) < (sizeY_+src.sizeY_)/2) );
}

subWindow
subWindow::operator*( float scale )
{
  return subWindow( centerX_, centerY_,
		    rint(sizeX_*scale), rint(sizeY_*scale) );
}

int
subWindowList::getSize()
{
  return subWinList_.size();
}

void
subWindowList::addSubWindow( const subWindow &subWin )
{
  subWinList_.push_back( subWin );
}

subWindow
subWindowList::getSubWindow( int i )
{
  return subWinList_[i];
}

void
subWindowList::delSubWindow( int i )
{
  vector<subWindow>::iterator delPos = subWinList_.begin();
  while ( i-- > 0 ) delPos++;
  subWinList_.erase(delPos);
}

subWindowList &
subWindowList::operator=( const subWindowList &src )
{
  subWinList_ = src.subWinList_;
  return *this;
}

int
sortedSubWindowList::getSize()
{
  return subWinList_.size();
}

void
sortedSubWindowList::addSubWindow( float key, const subWindow &subWin )
{
  subWinList_.insert( pair<float,subWindow>(key,subWin) );
}

subWindow
sortedSubWindowList::getSubWindow( int i )
{
  multimap<float,subWindow,keyComp>::iterator retPos = subWinList_.begin();
  while ( i-- > 0 ) retPos++;
  return retPos->second;
}

void
sortedSubWindowList::delSubWindow( int i )
{
  multimap<float,subWindow,keyComp>::iterator delPos = subWinList_.begin();
  while ( i-- > 0 ) delPos++;
  subWinList_.erase(delPos);
}

sortedSubWindowList &
sortedSubWindowList::operator=( const sortedSubWindowList &src )
{
  subWinList_ = src.subWinList_;
  return *this;
}

void
sortedSubWindowList::scaleAllKeys( float max, float min )
{
  float scale = max-min;

  sortedSubWindowList newList;
  multimap<float,subWindow,keyComp>::iterator iter = subWinList_.begin();
  do {
    newList.addSubWindow( (iter->first-min)/scale, iter->second );
  } while ( ++iter != subWinList_.end() );
  operator=( newList );
}

void
subWindowListAnim::addSubWindow( int frm, const subWindow &subWin )
{
  if ( itv_.isNever() )
  {
    itv_.setInstant( frm );
    list_.push_back( subWin );
  }
  else
  {
    if ( itv_.isJustBefore(frm) )
    {
      itv_ += frm;
      list_.insert( list_.begin(), subWin );
    }
    else if ( itv_.isJustAfter(frm) )
    {
      itv_ += frm;
      list_.push_back( subWin );
    }
  }
}

const subWindow &
subWindowListAnim::getSubWindow( int frm ) const
{
  return list_[frm-itv_.getStart()];
}

subWindow &
subWindowListAnim::getSubWindow( int frm )
{
  return list_[frm-itv_.getStart()];
}
