// Copyright (c) 2012 by Zuse-Institute Berlin and the Technical University of Denmark.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     1. Redistributions of source code must retain the above copyright
//        notice, this list of conditions and the following disclaimer.
//     2. 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.
//     3. Neither the name of the copyright holders nor contributors may not
//        be used to endorse or promote products derived from this software
//        without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDERS NOR CONTRIBUTORS 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.

#ifndef CBF_CBF_HELPER_H
#define CBF_CBF_HELPER_H

#include "sysres.h"
#include "cbf-data.h"


/*
 * The bucketsort function will read the integer sequence
 *   val[idx[0]], val[idx[1]], ...
 * and make changes to idx such that
 *   val[idx[0]], val[idx[1]], ...
 * is a stable sort (low to high) of the read sequence.
 */
CBFresponsee
  CBF_bucketsort(long long int maxval, long long int nnz, const long long int *val, long long int *idx);


/*
 * The CBFdyndata structure, makes it easy to populate
 * parts of the CBFdata structure dynamically. One example
 * would be to add bursts of triplets
 * (asubi, asubj, aval)
 *
 * Note that the cbf-helper module should ideally perform
 * all memory allocations and deallocations for the parts
 * of the CBFdata structure used dynamically!
 *
 * CBF_*_capacitysurplus will ensure room for coming elements,
 * by copying data to a new memory location if necessary.
 *
 * CBF_freedynamicallocations will deallocate only the parts
 * of the CBFdata structured that have been used dynamically.
 */
typedef struct CBFdyndata_struct {

  CBFdata *data;

  // Dynamic capacities (0 if not dynamically allocated)
  long long int mapstackdyncap;
  long long int varstackdyncap;
  long long int intvardyncap;
  int psdmapdyncap;
  int psdvardyncap;

  long long int objfdyncap;
  long long int objadyncap;
  long long int fdyncap;
  long long int adyncap;
  long long int bdyncap;
  long long int hdyncap;
  long long int ddyncap;

} CBFdyndata;

CBFresponsee
  CBF_freedynamicallocations(CBFdyndata *dyndata);

CBFresponsee
  CBF_map_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_map_adddomain(CBFdyndata *dyndata, CBFscalarconee domain, long long int dim);

CBFresponsee
  CBF_var_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_var_adddomain(CBFdyndata *dyndata, CBFscalarconee domain, long long int dim);

CBFresponsee
  CBF_intvar_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_intvar_add(CBFdyndata *dyndata, long long int idx);

CBFresponsee
  CBF_psdmap_capacitysurplus(CBFdyndata *dyndata, int surplus);

CBFresponsee
  CBF_psdmap_add(CBFdyndata *dyndata, int dim);

CBFresponsee
  CBF_psdvar_capacitysurplus(CBFdyndata *dyndata, int surplus);

CBFresponsee
  CBF_psdvar_add(CBFdyndata *dyndata, int dim);

CBFresponsee
  CBF_objf_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_objf_add(CBFdyndata *dyndata, int objfsubj, int objfsubk, int objfsubl, double objfval);

CBFresponsee
  CBF_obja_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_obja_add(CBFdyndata *dyndata, long long int objasubj, double objaval);

CBFresponsee
  CBF_objb_set(CBFdyndata *dyndata, double objbval);

CBFresponsee
  CBF_f_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_f_add(CBFdyndata *dyndata, long long int fsubi, int fsubj, int fsubk, int fsubl, double fval);

CBFresponsee
  CBF_a_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_a_add(CBFdyndata *dyndata, long long int asubi, long long int asubj, double aval);

CBFresponsee
  CBF_b_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_b_add(CBFdyndata *dyndata, long long int bsubi, double bval);

CBFresponsee
  CBF_h_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_h_add(CBFdyndata *dyndata, int hsubi, long long int hsubj, int hsubk, int hsubl, double hval);

CBFresponsee
  CBF_d_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_d_add(CBFdyndata *dyndata, int dsubi, int dsubk, int dsubl, double dval);

CBFresponsee
  CBF_varbound_capacitysurplus(CBFdyndata *dyndata, long long int surplus);

CBFresponsee
  CBF_varbound_addlower(CBFdyndata *dyndata, long long int idx, double val);

CBFresponsee
  CBF_varbound_addupper(CBFdyndata *dyndata, long long int idx, double val);

CBFresponsee
  CBF_varbound_addfix(CBFdyndata *dyndata, long long int idx, double val);

#endif
