/*
 *  This file is part of qpOASES.
 *
 *  qpOASES -- An Implementation of the Online Active Set Strategy.
 *  Copyright (C) 2007-2015 by Hans Joachim Ferreau, Andreas Potschka,
 *  Christian Kirches et al. All rights reserved.
 *
 *  qpOASES is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  qpOASES 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with qpOASES; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */


/**
 *  \file src/Flipper.cpp
 *  \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches
 *  \version 3.2
 *  \date 2007-2015
 *
 *  Implementation of the Flipper class designed to manage working sets of
 *  constraints and bounds within a QProblem.
 */


#include <qpOASES/Flipper.hpp>


BEGIN_NAMESPACE_QPOASES


/*****************************************************************************
 *  P U B L I C                                                              *
 *****************************************************************************/


/*
 *  F l i p p e r
 */
Flipper::Flipper( )
{
    R = 0;
    Q = 0;
    T = 0;
    
    init( );
}


/*
 *  F l i p p e r
 */
Flipper::Flipper(   uint_t _nV,
                    uint_t _nC
                    )
{
    R = 0;
    Q = 0;
    T = 0;
    
    init( _nV,_nC );
}


/*
 *  F l i p p e r
 */
Flipper::Flipper( const Flipper& rhs )
{
    R = 0;
    Q = 0;
    T = 0;

    copy( rhs );
}


/*
 *  ~ F l i p p e r
 */
Flipper::~Flipper( )
{
    clear( );
}


/*
 *  o p e r a t o r =
 */
Flipper& Flipper::operator=( const Flipper& rhs )
{
    if ( this != &rhs )
    {
        clear( );
        copy( rhs );
    }

    return *this;
}



/*
 *  i n i t
 */
returnValue Flipper::init(  uint_t _nV,
                            uint_t _nC
                            )
{
    clear( );

    nV = _nV;
    nC = _nC;

    return SUCCESSFUL_RETURN;
}



/*
 *  g e t
 */
returnValue Flipper::get(   Bounds* const _bounds,
                            real_t* const _R,
                            Constraints* const _constraints,
                            real_t* const _Q,
                            real_t* const _T 
                            ) const
{
    if ( _bounds != 0 )
        *_bounds = bounds;

    if ( _constraints != 0 )
        *_constraints = constraints;

    if ( ( _R != 0 ) && ( R != 0 ) )
        memcpy( _R,R, nV*nV*sizeof(real_t) );

    if ( ( _Q != 0 ) && ( Q != 0 ) )
        memcpy( _Q,Q, nV*nV*sizeof(real_t) );

    if ( ( _T != 0 ) && ( T != 0 ) )
        memcpy( _T,T, getDimT()*sizeof(real_t) );

    return SUCCESSFUL_RETURN;
}


/*
 *  s e t
 */
returnValue Flipper::set(   const Bounds* const _bounds,
                            const real_t* const _R,
                            const Constraints* const _constraints,
                            const real_t* const _Q,
                            const real_t* const _T
                            )
{
    if ( _bounds != 0 )
        bounds = *_bounds;

    if ( _constraints != 0 )
        constraints = *_constraints;

    if ( _R != 0 )
    {
        if ( R == 0 )
            R = new real_t[nV*nV];

        memcpy( R,_R, nV*nV*sizeof(real_t) );
    }

    if ( _Q != 0 )
    {
        if ( Q == 0 )
            Q = new real_t[nV*nV];

        memcpy( Q,_Q, nV*nV*sizeof(real_t) );
    }

    if ( _T != 0 )
    {
        if ( T == 0 )
            T = new real_t[getDimT()];

        memcpy( T,_T, getDimT()*sizeof(real_t) );
    }

    return SUCCESSFUL_RETURN;
}



/*****************************************************************************
 *  P R O T E C T E D                                                        *
 *****************************************************************************/

/*
 *  c l e a r
 */
returnValue Flipper::clear( )
{
    if ( R != 0 )
    {
        delete[] R;
        R = 0;
    }
    
    if ( Q != 0 )
    {
        delete[] Q;
        Q = 0;
    }
    
    if ( T != 0 )
    {
        delete[] T;
        T = 0;
    }

    return SUCCESSFUL_RETURN;
}


/*
 *  c o p y
 */
returnValue Flipper::copy(  const Flipper& rhs
                            )
{
    return set( &(rhs.bounds),rhs.R, &(rhs.constraints),rhs.Q,rhs.T );
}


uint_t Flipper::getDimT( ) const
{
    if ( nV > nC )
        return nC*nC;
    else
        return nV*nV;
}


END_NAMESPACE_QPOASES


/*
 *  end of file
 */
