/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <MvRequestUtil.hpp>
#include <Assertions.hpp>

#include "DataObject.h"
#include "DrawingPriority.h"
#include "GraphicsEngine.h"
#include "MvLayer.h"
#include "ObjectList.h"

DataObject::DataObject ( int dataUnitId, long offset, long offset2,
                         const MvRequest& dataInfo ):
	Presentable   ( dataInfo ),
	myDataUnitId_ ( dataUnitId ),
	dimFlag_      ( 0 )
{
     // Set the verb, default is GRIB
     const char* dt = dataInfo("DATA_TYPE");
     if ( dt )
          myRequest_.setVerb( dt );
     else
          myRequest_.setVerb( "GRIB" );

     // Add dimension and position information
     // If the second index is not equal to the first one,
     // this data is a 2D field.
     // FAMI 032012: at the moment, dimension info is only related
     // to GRIB data. Review this code if this condition changes.
     if ( strcmp(dt,"GRIB") != 0 )
         return;
 
     int ndim = 1;
     myRequest_( "GRIB_POSITION" ) = offset;
     if ( offset != offset2 )
     {
          ndim = 2;
          myRequest_( "GRIB_POSITION" ) += offset2;
          if ( (const char*)dataInfo("WIND_MODE") )
              myRequest_("GRIB_WIND_MODE" ) = (const char*)dataInfo("WIND_MODE");
     }

     myRequest_( "GRIB_DIMENSION" )  = ndim;
     dimFlag_ = dimFlag_ | ndim;
}

DataObject::DataObject ( MvRequest& reqst ):
  Presentable ( reqst ),
  dimFlag_    ( 0 )
{
     //empty
}

DataObject::DataObject ( const DataObject &old ):
  Presentable   (old ),
  myDataUnitId_ (old.myDataUnitId_),
  dimFlag_      ( 0 ),
  legends_      (old.legends_),
  titleText_    (old.titleText_),
  titleRequest_ (old.titleRequest_)
{
  //segmentNameMap_ not copied.
}

bool
DataObject::AppendDataUnit ( int dataunitId, long offset, long offset2, const MvRequest& req )
{
     // Do not append if this is a new data
     if ( !this->Match(dataunitId,req) )
          return false;

     // Update position and dimension parameters
     int ndim = 1;
     myRequest_( "GRIB_POSITION" ) += offset;
     if ( offset != offset2 ) //two dimensional data
     {
          ndim = 2;
          myRequest_( "GRIB_POSITION" ) += offset2;
     }

     myRequest_( "GRIB_DIMENSION" ) += ndim;
     dimFlag_ = dimFlag_ | ndim;

     return true;
}

// Check if the current data and new data match
// True -> they match, False-> they do not match
bool
DataObject::Match ( int dataunitId, const MvRequest& req )
{
	// New data and current data are not from the same file -> return false
	if ( myDataUnitId_ != dataunitId ) 
		return false;

	// The request verbs are not the same -> return false
	if ( strcmp (myRequest_.getVerb(), req("DATA_TYPE") ))
		return false;

	return true;
}

DrawPriorMap
DataObject::DrawPriority( MvIconList& visdefList)
{
	DrawPriorMap drawPriorMap;

	// Each data unit has a unique identifier - which is
	// the key to retrieve it 
	require (myDataUnitId_ > 0);

	// Get DrawingPriority from Page
	DrawingPriority& tmpDrawingPriority = this->GetDrawPriority();

	// Create Priority string based on only the first visdef. 
	// It assumes that all the other visdefs will have the same "priority"
	MvListCursor vdCursor;
	vdCursor = visdefList.begin();
	MvIcon& visDef = *( vdCursor );
	MvRequest visRequest = visDef.Request();
			
	int visDefId = visDef.Id ();
	Cached drawPrior = tmpDrawingPriority.DrawSegmentName ( myDataUnitId_,
						     visRequest,
						     visDefId  );
	string dataString ( (const char*) drawPrior );
	pair <int, int> tmpPair ( this->Id(), visDefId );
	drawPriorMap [ dataString ] = tmpPair;

	return drawPriorMap;
}

DrawPriorMap
DataObject::DrawPriority( )
{
	// Each data unit has a unique identifier - which is
	// the key to retrieve it 
	require (myDataUnitId_ > 0);

	// Retrieve the Icon Data Base
	MvIconDataBase& dataBase = IconDataBase();

	// Retrieve the DataUnit
	// (the object only stores its dataunit Id and index)
	MvIcon  dataUnit;
	//if ( dataBase.RetrieveDataUnit (myDataUnitId_, dataUnit) == false)
   if ( dataBase.RetrieveIconFromList (DB_DATAUNIT, myDataUnitId_, dataUnit) == false)
	{
//		cout << "DataObject::Draw() -> No Data Unit" << endl;
		return DrawPriorMap();
	}

	// Retrieve the VisDefs associated to the DataUnit
	MvIconList visdefList;
	RetrieveMyVisDefList ( dataUnit, visdefList );

	return DrawPriority(visdefList);
}

#if 0
// Don't attempt to get visdefs, they're given as input
void DataObject::DrawVisDef(MvIcon& visDef, string& /* segmentName */)
{
  // Retrieve the Graphics Engine
  GraphicsEngine& ge = this->GetGraphicsEngine();

  MvIconDataBase&   dataBase = IconDataBase();

  MvIcon  dataUnit;
  if ( dataBase.RetrieveDataUnit (myDataUnitId_, dataUnit) == false)
    {
      cout << "DataObject::Draw() -> No Data Unit" << endl;
      return;
    }

//D  segmentNameMap_[visDef.Id()] = segmentName;

  // Call the graphics Engine
  ge.Draw ( dataUnit, myRequest_, visDef, this->GetCanvas() );
}
#endif

void DataObject::DrawDataVisDef()
{
   // Retrieve the Graphics Engine and the data base info
   GraphicsEngine& ge = GetGraphicsEngine();
   MvIconDataBase& dataBase = IconDataBase();

   // Retrieve the DataUnit
   MvIcon  dataUnit;
   //if ( dataBase.RetrieveDataUnit (myDataUnitId_, dataUnit) == false)
   if ( dataBase.RetrieveIconFromList (DB_DATAUNIT, myDataUnitId_, dataUnit) == false)
   {
      cout << "ERROR: DataObject::Draw(DataVisDef) -> No Data Unit" << endl;
      return;
   }

   // Retrieve all VisDefs associated to the DataUnit
   MvIconList visdefList;
   bool defaultVD = RetrieveMyVisDefList ( dataUnit, visdefList );

   // Update DataBase if this is the first plot (i.e. not a result of a dropping
   // icon) with the NDimensional flag. This could not be done earlier, during
   // the Drop procedure, because this information is only available after
   // having decoded the whole DataObject and the task of inserting the DataObject
   // to the DataBase was done earlier.
   bool first = false;
   MvRequest dataRequest = dataUnit.Request();
   if ( !(const char*)dataRequest("_NDIM_FLAG" ) )
   {
      dataRequest("_NDIM_FLAG" ) = dimFlag_;
      dataBase.UpdateIcon(DB_DATAUNIT,dataUnit.Id(),dataRequest);
      first = true;
   }

   // Call the Graphics Engine to store the Layer info.
   DrawLayerInfo( dataUnit.Id() );

   // Call the Graphics Engine to store the Data and Visdef info.
   ge.DrawDataVisDef ( dataUnit,myRequest_,visdefList,dimFlag_ );

   // Update DataBase if this is the first plot and the visdefList is a default one.
   // If visdefList is not a default one, this means that the DataBase was already
   // updated earlier.
   // In the first plot, before calling ge.Draw, the list of visdefs contains
   // all valid visdefs. After calling ge.Draw, it contains only the visdefs
   // used in the plotting. If this is not the first plot, the Drop scheme (executed
   // earlier) should update (add/replace/delete) the list of visdefs accordingly.
   if ( first && defaultVD )
   {
      // Insert new VD
      MvListCursor iCursor;
      for ( iCursor = visdefList.begin(); iCursor != visdefList.end(); ++iCursor)
      {
         MvRequest req = (*( iCursor )).Request();
         dataBase.InsertVisDef ( req, myDataUnitId_, dataUnit);
      }
   }
}

#if 0
// EraseDraw - 
// Erase data object drawing on canvas
// If visDefId is zero, all drawing of this DataObject should be
//	removed
void 
DataObject::EraseDraw( int visDefId )
{
  require (myDataUnitId_ > 0);
  
  // Retrieve the canvas
  Canvas& canvas = this->GetCanvas();
  
  // Erase all pairs
  SegmentNameMap::iterator ii;
  for ( ii = segmentNameMap_.begin(); ii != segmentNameMap_.end(); ++ii )
    {

      int visId = (*ii).first; 
      if ( visDefId && (visDefId != visId ) ) continue;
      
      string dataString = (*ii).second;
      
//D      if ( canvas.RemoveForAll(myParent_->Id(),dataString) ) 
	{
	  this->RemoveLegend ( dataString );
	  myParent_->NeedsRedrawing ( true );
	}
    }
}

void 
DataObject::EraseDefaultDraw ()
{
	EraseDraw();
}
#endif

bool
DataObject::RetrieveMyVisDefList ( MvIcon& dataUnit, MvIconList& visdefList )
{
   bool usingDefault = false;

   // Retrieve the Icon Data Base
   MvIconDataBase& dataBase = IconDataBase();

   // Retrieve the VisDefs associated to the DataUnit
   if ( dataBase.RetrieveVisDefList ( dataUnit, visdefList ) )
   {
      // Check if there is any valid visdef
      if ( ObjectList::CheckValidVisDefList ( myRequest_.getVerb(), visdefList ) )
         return usingDefault;  //found a valid visdef
   }

   // Check if there is a parent DataUnit
   int parentDataUnitId = dataUnit.ParentId();
   if ( parentDataUnitId )
   {
      // There is a parent, look for its Visdefs
      MvIcon parentDataUnit;
      dataBase.RetrieveIconFromList ( DB_DATAUNIT, parentDataUnitId, parentDataUnit );
      dataBase.RetrieveVisDefList ( parentDataUnit, visdefList );

      // Check that the parent has a valid visdef for this dataunit
      if ( ObjectList::CheckValidVisDefList ( myRequest_.getVerb(),visdefList ) )
         return usingDefault;  //found a valid visdef
   }

   // There is no visdef associated to the dataunit -> get a default visdef.
   // If the dataunit has a flag indicating a default visdef then apply it (A).
   // Otherwise, get its default visdef (B).

   // (A) Verify if the dataunit suggests an specific visdef
   MvRequest reqAux = dataUnit.Request();
   if ( (const char*)reqAux("_VISDEF") )
   {
      visdefList.clear();
      MvRequest visdefRequest = ObjectList::UserDefaultRequest ( (const char*)reqAux("_VISDEF") );
      MvIcon newVisdef (visdefRequest);
      visdefList.push_back(newVisdef);
      usingDefault = true;
   }
   else
   {
      // (B) Retrieve the default visdef (it could be either
      // in the Page, SuperPage or in the Root).
      usingDefault = this->DefaultVisDefList ( myRequest_.getVerb(), visdefList );
   }

   // If it is a default visdef, update some parameters
   if ( usingDefault )
      this->UpdateVisDef (reqAux,visdefList);

   return usingDefault;
}

#if 0
void
DataObject::SetTitle ( const MvRequest& treq )
{
	MvRequest rqst = treq;

	// Should have only one package, use the latest
	int nPacks  = rqst ( "$METVIEW_TITLE_PACKAGE_COUNT" );
	Cached titlePackageName = "$METVIEW_TITLE_PACKAGE_";
	titlePackageName = titlePackageName + nPacks;

	int nValues = rqst.countValues ( titlePackageName );
	if ( nValues )
	{
		titleText_.resize ( nValues );

		for ( int i = 0; i < nValues; i++ )
			titleText_ [i] = rqst ( titlePackageName, i );

		// Save Text information related to Grib ('GRIB_TEXT_...')
		MvRequest auxReq = rqst.getSubrequest("$METVIEW_TITLE_PACKAGE_1_REQUEST");
                titleRequest_ = empty_request(NULL); 
                CopySomeParameters (auxReq,titleRequest_,"GRIB_TEXT");
	}
	else if ( IsParameterSet ( rqst, "TEXT_LINE_1" ) )
	{
		if ( IsParameterSet ( rqst, "TEXT_LINE_COUNT" ) )
			CopySomeParameters ( rqst, myRequest_, "TEXT_LINE_" );
		else
		{
			myRequest_ ( "TEXT_LINE_1" ) = (const char*)rqst ( "TEXT_LINE_1" );
			myRequest_.unsetParam ( "TEXT_LINE_COUNT" );
		}
	}
}
#endif

void
DataObject::GetTitle ( MvRequest& rqst, int* order )
{
	int i;

	// Set TEXT_ORIGIN, internal parameter between PlotMod and Magics
	this->SetTextOrigin (rqst);

        char name[50];
        sprintf(name,"TEXT_LINE_%d",*order);

	int nValues = titleText_.size ();
	if ( nValues ) // There is an automatic title package
	{
		rqst ( "$METVIEW_TITLE_PACKAGE_COUNT" ) = *order;  

		Cached titlePackageName = "$METVIEW_TITLE_PACKAGE_";
		titlePackageName = titlePackageName + *order;

		rqst ( titlePackageName ) = titleText_[0];
		for ( i = 1; i < nValues; i++ )
			rqst ( titlePackageName ) += titleText_[i];

		// Add title information related to the Grib ('GRIB_TEXT_...')
                CopySomeParameters (titleRequest_,rqst,"GRIB_TEXT");

		( *order )++;
	}
	else //Title defined by the user
	{
                // Merge 2 TEXT requests
                const char* origin =  rqst("TEXT_ORIGIN");
		if (origin == Cached("AUTOMATIC"))
		{
			// Clear user TEXT_LINE_*
			char saux[13];
			strcpy(saux,"TEXT_LINE_");
			int size = strlen(saux);
			int j    = myRequest_("TEXT_LINE_COUNT");
			rqst.unsetParam ("TEXT_LINE_COUNT");
			for (i = 1; i <= j; i ++)
			{
				sprintf(saux+size,"%d",i);
				rqst.unsetParam ( saux );
			}

			// Copy TEXT parameters
			CopySomeParameters (myRequest_, rqst, "TEXT_", (bool)false);
		}
		else if (origin == Cached("BOTH") || origin == Cached("MERGE") )
			 MergeTextParameters (myRequest_, rqst, false);
		
///F		( *order ) = rqst("TEXT_LINE_COUNT");

		// Now we have already set the Text request.
		// For the Magics point of view, if the title came from
		// an  Application which produces its own title (p.e.,
		// XSection), it is necessary to reset TEXT_ORIGIN
		// to USER.
		if ( !this->MagicsTitle () )
			rqst("TEXT_ORIGIN") = Cached("USER");
	}
}

void
DataObject::SetTextOrigin ( MvRequest& request )
{
	// If TEXT_ORIGIN has already been set, return.
	if ( IsParameterSet (request, "TEXT_ORIGIN" ) )
	{
	    string val = (const char*)request("TEXT_ORIGIN");
	    if( val != "NOTSET" )
		return;
	}

	// Check if TEXT_AUTOMATIC, TEXT_USER and TEXT_MERGE has 
	// been set (these are PlotMod parameters and 
	// must not be sent to Magics)
	MvRequest reqAux = request;
	bool expand = false;
	if ( IsParameterSet (reqAux, "TEXT_AUTOMATIC" ) )
		request.unsetParam ( "TEXT_AUTOMATIC" );
	else
		expand = true;

	if ( IsParameterSet (reqAux, "TEXT_USER" ) )
		request.unsetParam ( "TEXT_USER" );
	else
		expand = true;

	if ( IsParameterSet (reqAux, "TEXT_MERGE" ) )
		request.unsetParam ( "TEXT_MERGE" );
	else
		expand = true;

	// Expand request in order to retrieve the default values
	if ( expand )
		reqAux = ObjectList::ExpandRequest(reqAux,EXPAND_DEFAULTS);

	// Set TEXT_ORIGIN
	Cached yes("YES");
	bool autoText  = (reqAux ( "TEXT_AUTOMATIC" ) == yes ) ? true : false;
	bool userText  = (reqAux ( "TEXT_USER" )      == yes ) ? true : false;
	bool mergeText = (reqAux ( "TEXT_MERGE" )     == yes ) ? true : false;

	if ( mergeText )
		request ("TEXT_ORIGIN") = Cached("MERGE");
	else if ( autoText && userText )
		request ("TEXT_ORIGIN") = Cached("BOTH");
	else if ( !autoText && userText )
		request ("TEXT_ORIGIN") = Cached("USER");
	else if ( autoText && !userText )
		request ("TEXT_ORIGIN") = Cached("AUTOMATIC");
	else
		request ("TEXT_ORIGIN") = Cached("NONE");

	// Set TEXT_LINE_COUNT. For MAGICS point of view the default
	// value is 1. However, for PLOTMOD this value must be set.
	int ncount = request ("TEXT_LINE_COUNT");
	if ( userText && ncount == 0 )
		  request ("TEXT_LINE_COUNT") = 1;
}

#if 0
void
DataObject::SetLegend ( const MvRequest& rqst )
{
	// Should have only one package
	int nPackages = rqst ( "$METVIEW_LEGEND_PACKAGE_COUNT" );
	if ( nPackages == 1 )
	{
		Cached titlePackageName = Cached ( "$METVIEW_LEGEND_PACKAGE_" ) +
						   nPackages;
		int nValues = rqst.countValues ( titlePackageName );
		vector<int> values ( nValues );
		for ( int i = 0; i < nValues; i++ )
			 values [i] = rqst ( titlePackageName, i );

		Cached fileStoreName = Cached ( "METVIEW_LEGEND_STORE_FILE_" ) +
				       nPackages;
		Cached fileName = rqst ( fileStoreName );
		string name = (const char *) fileName;
		string typeName = (const char* ) rqst ("TYPE");
		legends_ [ typeName ] = LegendPackage ( name, values );
	}
}
#endif

bool
DataObject::GetLegend ( MvRequest& rqst, int* order )
{
	// Present Magics Limit
	if ( *order > MAX_LEGENDS_PACKAGE )
		return false;

	if ( legends_.size () )
	{
		for ( LegendsMap::iterator j = legends_.begin ();
		      j != legends_.end (); ++j )
		{
			Cached titlePackageName = Cached ( "$METVIEW_LEGEND_PACKAGE_" ) +
						  *order;
			rqst ( "$METVIEW_LEGEND_PACKAGE_COUNT" ) = *order;

			LegendPackage legendPackage = (*j).second;

			rqst ( titlePackageName ) = (legendPackage.second)[0];
			for ( unsigned int i = 1; i < (legendPackage.second).size (); i++ )
				rqst ( titlePackageName ) += (legendPackage.second)[i];

			Cached fileName = Cached ( "METVIEW_LEGEND_STORE_FILE_" ) + *order;
			rqst ( fileName ) = ( legendPackage.first ).c_str();

			( *order ) ++;
       			if ( *order > MAX_LEGENDS_PACKAGE )
				return true;
		}
		return true;
	}

	return false;
}

#if 0
bool
DataObject::RemoveLegend ( string name )
{
	// Only one legend per data allowed
	legends_.clear ();
	
	LegendsMap::iterator i = legends_.find ( name );
	if ( i != legends_.end() )
	{
		legends_.erase ( i );
		return true;
	}
	return false;
}
 
MvRequest
DataObject::DataRequest ()
{
	MvRequest dataRequest;

	MvIconDataBase& dataBase = this->IconDataBase ();
	MvIcon dataUnitIcon;
	dataBase.RetrieveDataUnit ( myDataUnitId_, dataUnitIcon );
	const MvRequest dataunitRequest = dataUnitIcon.Request ();

	if ( Cached ( myRequest_.getVerb () ) == GRIB )
	{
		dataRequest = dataunitRequest;		
		dataRequest ( "OFFSET" ) = myDataIndex_;
		dataRequest ( "LENGTH" ) = 0;
	}
	else if ( Cached ( myRequest_.getVerb () ) == IMAGE )
	{
		dataRequest.setVerb ( "IMAGE" );
		dataRequest ( "PATH" ) = (const char*)dataunitRequest ( "PATH" ); 
		dataRequest ( "OFFSET" ) = myDataIndex_;
		dataRequest ( "LENGTH" ) = 0;
		const char* name = dataunitRequest("_NAME");
		if ( name )
		     dataRequest ( "_NAME" ) = name; 
	}
	else if ( Cached ( myRequest_.getVerb () ) == VECTOR_FIELD )
	{
		dataRequest.setVerb ( "VECTOR_FIELD" );
		MvRequest gribRequest = dataunitRequest;
		gribRequest ( "OFFSET" ) = myDataIndex_;
		gribRequest ( "LENGTH" ) = 0;
		dataRequest ( "U_COMPONENT" ) = gribRequest;

		gribRequest = dataunitRequest;
		gribRequest ( "OFFSET" ) = myDataIndex2_;
		gribRequest ( "LENGTH" ) = 0;
		dataRequest ( "V_COMPONENT" ) = gribRequest;
	}
	else
	{
		dataRequest = dataunitRequest;		
	}
	return dataRequest;
}			

// Overridden from Presentable. Although DataObject is a Presentable,
// it must be trated differently. It's got no children, and VisDefs
// are attached through it's dataunit id, not the presentable id.
void DataObject::DuplicateChildren(const Presentable& old)
{
  MvIconDataBase& dataBase = IconDataBase();
  MvIconDataBase& oldDB = old.IconDataBase(); 
  MvIcon visDef;
  
  // VisDefs
  oldDB.DataUnitVisDefRelationRewind();

  while ( oldDB.NextVisDefByDataUnitId(DataUnitId(),visDef) )
    dataBase.DataUnitVisDefRelation(DataUnitId(),visDef.Id() );
}
#endif

bool
DataObject:: MagicsTitle ()
{
	const char* dataType = myRequest_("DATA_TYPE");
	if ( dataType && (strcmp (dataType, "GRIB")         == 0 || 
		          strcmp (dataType, "GEOPOINTS")    == 0 ||
		          strcmp (dataType, "IMAGE")        == 0 ||
		          strcmp (dataType, "BUFR")         == 0 ))
		return true;
	else
		return false;
}

void DataObject::DataUnit(MvIcon  &dataUnit)
{
   // Retrieve the data base info
   MvIconDataBase& dataBase = IconDataBase();

   // Retrieve the DataUnit
	//if (dataBase.RetrieveDataUnit (myDataUnitId_, dataUnit) == false)
   if (dataBase.RetrieveIconFromList (DB_DATAUNIT, myDataUnitId_, dataUnit) == false)
       cout << "ERROR: DataObject::Draw(DataVisDef) -> No Data Unit" << endl;
}

// Update some visdef parameters only for the following cases:
// a) Scatter/GeoScatter applications and parameter "VALUES" is defined
//    and visdef is MSYMB
// b) Vector_Scatter/Geo_Vector_Scatter applications and parameter "VALUES"
//    is defined and visdef is MWIND
void
DataObject::UpdateVisDef ( MvRequest dataUnit,MvIconList& iconList )
{
	// Get application name without the prefix
	string verb   = dataUnit.getVerb();
	size_t ipos   = verb.find("_");
	string sapp   = verb.substr(ipos+1);
	string prefix = verb.substr(0,ipos);

	// Update visdef parameters only for the following applications
	if ( sapp == "XY_POINTS" || sapp == "GEO_POINTS" )
	{
		// Update only if parameter *_VALUES or *_VARIABLE_NAME is given
		string param1 = prefix + "_VALUES";
		string param2 = prefix + "_VARIABLE_NAME";
		string param2Sval;
		if ( (const char*)dataUnit(param2.c_str()) )
			param2Sval = (const char*)dataUnit(param2.c_str());

		if ( (const char*)dataUnit(param1.c_str()) || param2Sval.size() )
		{
			// Update only MSYMB visdefs
			MvListCursor vdc;
			for ( vdc = iconList.begin(); vdc != iconList.end(); ++vdc)
			{
				MvIcon& visDef = *( vdc );
				MvRequest vdRequest = visDef.Request();
				if ( strcmp(vdRequest.getVerb(),"MSYMB") == 0 )
				{
					vdRequest("SYMBOL_TABLE_MODE") = "ADVANCED";
					visDef.SaveRequest(vdRequest);
				}
			}
		}
	}
	else if ( sapp == "XY_VECTORS" || sapp == "GEO_VECTORS" )
	{
		// Update only if parameter *_VALUES or *_VARIABLE_NAME is given
		string param1 = prefix + "_VALUES";
		string param2 = prefix + "_VARIABLE_NAME";
		string param2Sval;
		if ( (const char*)dataUnit(param2.c_str()) )
			param2Sval = (const char*)dataUnit(param2.c_str());

		if ( (const char*)dataUnit(param1.c_str()) || param2Sval.size() )
		{
			// Update only MWIND visdefs
			MvListCursor vdc;
			for ( vdc = iconList.begin(); vdc != iconList.end(); ++vdc)
			{
				MvIcon& visDef = *( vdc );
				MvRequest vdRequest = visDef.Request();
				if ( strcmp(vdRequest.getVerb(),"MWIND") == 0 )
				{
					vdRequest("WIND_ADVANCED_METHOD") = "ON";
					visDef.SaveRequest(vdRequest);
				}
			}
		}
	}
	else if ( sapp == "HOR_BAR" || sapp == "VER_BAR" )
	{
		// Update MGRAPH visdefs
		MvListCursor vdc;
		for ( vdc = iconList.begin(); vdc != iconList.end(); ++vdc)
		{
			MvIcon& visDef = *( vdc );
			MvRequest vdRequest = visDef.Request();
			if ( strcmp(vdRequest.getVerb(),"MGRAPH") == 0 )
			{
				vdRequest("GRAPH_TYPE") = "BAR";
				visDef.SaveRequest(vdRequest);
			}
		}
	}

	// Update database
	// It seems that this update is not need (keep an eye...)
}
