//===========================================================================
// Copyright (C) 1998, 2000-2007, 2010, 2011, 2012 SINTEF ICT, Applied
// Mathematics, Norway.
//
// This file is part of GoTools
//
// 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 for more details.                           
//
// You should have received a copy of the GNU General Public License      
// along with this program; if not, see <http://www.gnu.org/licenses>
//
// Contact information: E-mail: tor.dokken@sintef.no                      
// SINTEF ICT, Department of Applied Mathematics,                         
// P.O. Box 124 Blindern,                                                 
// 0314 Oslo, Norway.                                                     
//
// Other licenses are also available for this software, notably licenses
// for:
// - Building commercial software.                                        
// - Building software whose source code you wish to keep private.        
//===========================================================================

#include "GoTools/geometry/SplineSurface.h"
#include "GoTools/geometry/SplineCurve.h"


using namespace Go;


//===========================================================================
void SplineSurface::raiseOrder(int raise_u, int raise_v)
//===========================================================================
{
    ALWAYS_ERROR_IF(raise_u < 0 || raise_v < 0,
		    "Order to raise by must be positive!");

    // We're raising in the u-direction first.
    bool rat = rational_;
    std::vector<double>::iterator coef_iter = (rat) ? rcoefs_.begin() : coefs_.begin();
    int rdim = (rat) ? dimension() + 1 : dimension();
    if (raise_u > 0) {
	swapParameterDirection();
	// This makes for a really easy routine. We now raise in v-direction.
	SplineCurve huge_curve(numCoefs_v(), order_v(),
			       basis_v().begin(), coef_iter,
			       rdim*numCoefs_u(), false);

	huge_curve.raiseOrder(raise_u);
	basis_v_ = huge_curve.basis();
	coefs_.empty();
	if (rat) {
	    rcoefs_.assign(huge_curve.coefs_begin(), huge_curve.coefs_end());
	} else {
	    coefs_.assign(huge_curve.coefs_begin(), huge_curve.coefs_end());
	}
	swapParameterDirection();
    }

    // We then raise in the v-direction.
    coef_iter = (rat) ? rcoefs_.begin() : coefs_.begin();
    if (raise_v > 0) {
	SplineCurve huge_curve(numCoefs_v(), order_v(),
			       basis_v().begin(), coef_iter,
			       rdim*numCoefs_u(), false);

	huge_curve.raiseOrder(raise_v);
	basis_v_ = huge_curve.basis();
	coefs_.empty();
	if (rat) {
	    rcoefs_.assign(huge_curve.coefs_begin(), huge_curve.coefs_end());
	} else {
	    coefs_.assign(huge_curve.coefs_begin(), huge_curve.coefs_end());
	}
    }

    if (rat) {
	updateCoefsFromRcoefs();
    }
}
