/*
    Copyright (C) 1998  Dennis Roddeman
    email: dennis.roddeman@uibk.ac.at

    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; either version 2 of the License, or
    (at your option) any later version.

    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, write to the Free Software Foundation 
    59 Temple Place, Suite 330, Boston, MA, 02111-1307, USA
*/

#include "tochnog.h"

void area_element_group( long int version )

{
  long int element=0, max_element=0, inol=0, nnol=0, inod=0, all=0, length=0,
    itmp=0, iarea=0, max_area_element_group=0, area_element_group[3], 
    element_group=0, ldum=0, el[MNOL+1], nodes[MNOL];
  double rdum=0., ddum[MDIM];

  db_max_index( AREA_ELEMENT_GROUP, max_area_element_group, VERSION_NORMAL, GET );
  if ( max_area_element_group>=0 ) {
    db_delete( ELEMENT_GROUP, version );
    db_max_index( ELEMENT, max_element, version, GET );
    for ( iarea=0; iarea<=max_area_element_group; iarea++ ) {
      if ( db_active_index( AREA_ELEMENT_GROUP, iarea, VERSION_NORMAL ) ) {
        db( AREA_ELEMENT_GROUP, iarea, area_element_group, ddum, 
          ldum, VERSION_NORMAL, GET );
        for ( element=0; element<=max_element; element++ ) {
          if ( db_active_index( ELEMENT, element, version ) ) {
            db( ELEMENT, element, el, ddum, length, version, GET );
            nnol = length - 1; array_move( &el[1], nodes, nnol );
            all = 1;
            for ( inol=0; inol<nnol; inol++ ) {
              inod = nodes[inol];
              geometry( inod, ddum, area_element_group, itmp, rdum, ddum, rdum,
                ddum, NODE_START_REFINED, PROJECT_EXACT, version );
              if ( !itmp ) all = 0;
            }
            if ( all ) {
              element_group = area_element_group[2];
              length = 1; db( ELEMENT_GROUP, element, &element_group, ddum, 
                length, version, PUT );
            }
          }
        }
      }
    }
  }

}

long int get_group_data( long int idat, long int gr, double new_unknowns[],
  double values[], long int &nvalue, long int task )

{
  long int i=0, n=0, idep=0, max_dep=0, found=0, go_ahead=0,
    iuknwn=0, ival=0, nval=0, length=0, ldum=0, 
    idum[1], dof_label[MUKNWN], *dependency_item=NULL;
  double tmp=0., time_current=0., dtime=0.,
    ddum[1], *dependency_diagram=NULL;

  db_max_index( DEPENDENCY_ITEM, max_dep, VERSION_NORMAL, GET );
  if ( max_dep>=0 ) {
    db( DOF_LABEL, 0, dof_label, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
    for ( idep=0; idep<=max_dep && !found; idep++ ) {
      if ( db_active_index( DEPENDENCY_ITEM, idep, VERSION_NORMAL ) ) {
        dependency_item = db_int( DEPENDENCY_ITEM, idep, VERSION_NORMAL );
        n = dependency_item[3];
        if ( n<2 ) db_error( DEPENDENCY_ITEM, idep );
        if ( scalar_iabs(dependency_item[0])==idat && dependency_item[1]==gr ) {
          if ( dependency_item[2]==-TIME_CURRENT ) {
            db( DTIME, 0, idum, &dtime, ldum, VERSION_NEW, GET );
            db( TIME_CURRENT, 0, idum, &time_current, 
              ldum, VERSION_NORMAL, GET_IF_EXISTS );
            go_ahead = 1;
            tmp = time_current + dtime;
          }
          else {
            array_member(dof_label,dependency_item[2],nuknwn,iuknwn);
            if ( iuknwn>=0 && iuknwn<=nuknwn ){
              go_ahead = 1;
              tmp = new_unknowns[iuknwn];
            }
            else
              db_error( DEPENDENCY_ITEM, idep );
          }
          if ( go_ahead ) {
            found = 1;
            dependency_diagram = db_dbl( DEPENDENCY_DIAGRAM, idep, VERSION_NORMAL );
            length = db_len( DEPENDENCY_DIAGRAM, idep, VERSION_NORMAL );
            if ( length%n!=0 ) db_error( DEPENDENCY_DIAGRAM, idep );
            if ( db_fixed_length( idat ) ) {
              nval = db_data_length( idat );
              if ( length%nval!=0 ) db_error( DEPENDENCY_DIAGRAM, idep );
            }
            else
              nval = ( length -n ) / n;
            for ( ival=0; ival<nval; ival++ ) {
              if      ( tmp<dependency_diagram[0] ) 
                values[ival] = dependency_diagram[n+ival*n+0];
              else if ( tmp>dependency_diagram[n-1] ) 
                values[ival] = dependency_diagram[n+ival*n+n-1];
              else {
                for( i=0; i<n-1; i++ ) {
                  if ( dependency_diagram[i+1]<=dependency_diagram[i] )
                    db_error( DEPENDENCY_DIAGRAM, idep );
                  if ( tmp>=dependency_diagram[i] &&
                       tmp<=dependency_diagram[i+1] ) {
                    values[ival] = dependency_diagram[n+ival*n+i] +
                      (tmp-dependency_diagram[i])*
                      (dependency_diagram[n+ival*n+i+1]-
                         dependency_diagram[n+ival*n+i])
                       /(dependency_diagram[i+1]-dependency_diagram[i]);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  if ( !found ) 
    found = db( idat, gr, idum, values, nvalue, VERSION_NORMAL, task );
  else
    nvalue = nval;

  return found;
}
