/***************************************************************************

    supportware
    Copyright (C) 2001-2008 by c.holzheuer
    c.holzheuer@sourceworx.org

    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.

***************************************************************************/


#include <dditemtree.h>
#include <dditemset.h>
#include <ddiourl.h>
#include <ddwebpage.h>
#include <dduserid.h>


/**
	Constructor.
*/

dditemtree::dditemtree()
{
}


/**
	Constructor.
*/

dditemtree::dditemtree( const ddstring& name )
: dditem( name )
{
}



/**
	Standard Constructor.
*/

dditemtree::dditemtree( const ddstring& name, const ddstring& value, const ddstring& call, size_t access )
: dditem( name )
{
 _access = access;
 _value = value; 
 _param = call;
}


/**
	Destructor.
*/

dditemtree::~dditemtree()
{
	
}




/**
	Clear all child items: call @see clear_value() for all childitem that have
	a name. This is usually used to clear input forms.
	Prototype only, throws base call exception.
*/

dditem& dditemtree::clear_children()
{
  const ddmapindex& idx = get_index();
	ddmapindex::const_iterator pos = idx.begin();
	for( ; pos != idx.end(); ++pos )
		_data.get_entry( (*pos).second ).clear_value();
	return *this;	
}


/**
	Create a string representation of this object.
*/

ddstring dditemtree::join() const
{
	ddstring result;
	for( int i = 0; i < _data.size(); i++ )
		result.append ( _data[i]->to_string() );
	return result;
}


/**
	Synchronize the datafields of the cgi object with the fields of 
	this item tree.
	@see ddwebcgi
	
*/

void dditemtree::sync( ddwebcgi& cgi )
{
	const ddmapindex& index = get_index();
	ddmapindex::const_iterator pos = index.begin();
	
	for( ; pos != index.end(); ++pos )
	{
		
		/*
			über alle form felder, falls das feld _auch_
			im cgi vorhanden dann die daten übernehmen.
			NEU: anderfalls das formfeld löschen
			NEU: Nein, doch nicht
		*/
		
		ddwebcgi::iterator pos2 = cgi.find( (*pos).first );
    if( pos2 != cgi.end() )
			_data[(*pos).second]->from_string( (*pos2).second );		
		//else
		//	_data[(*pos).second]->clear_value();
		
	}
}




/**
	Create a string representation of this object.
*/

ddstring dditemtree::to_string() const
{
	// hack
  if( !_value.empty() )
		return dditem::to_string();
  return join();
}
	

/**
	Dump this object to std::out for dubugging purposes.
*/

void dditemtree::dump() const
{
	cout << "itemtree: name: " << get_name() << endl;
	for( int i=0; i<_data.size(); ++i )
		_data[i]->dump();
}


/**
	Create and add a child.
*/

void dditemtree::add_child( const ddstring& name, const ddstring& value )
{
	add_child( new dditem( name, value ) );
}


/**
	Add a child. Kill old child, if existent.
*/

void  dditemtree::add_child( dditem* child )
{
	if( !child->get_name().empty() )
	{
    // kill old child
   	int i = _data.index_of( child->get_name() );
    if( i>=0 )
    {
			delete _data[i];
			_data[i] = child;
		}
		else
		{
			_data.add_by_key( child->get_name(), child );
		}
	}
	else
	{
		_data.add( child );
	}
}


/**
	@return a deep copy of this item: All child items are alse cloned.
*/

dditem* dditemtree::clone() const
{
  dditemtree* item = new dditemtree( _name, _value, _param, _access );
  // entry-wise clone
  for( int i=0; i<_data.size(); ++i )
  	item->add_child( _data[i]->clone() );
	return item;
}


/**
	Write the content of this item into the buffer of the given pagelet.
  If the accessrights of the current user are not sufficient the access this
  item, the content is silently ignored.
	@return 1 on success, -1 on error.	
*/

dd_result dditemtree::flush_content( ddwebpage& pagelet )
{

  // check accessrights
  if( !( get_access() & pagelet.get_user_id().get_access_rights() ) )
		return rs_ok;

	if( !_param.empty() )
		return pagelet.execute_call( _param, *this );

  // hack  
  if( !_value.empty() )
  {
		pagelet.get_buffer().append( dditem::to_string() );
		return rs_ok;
	}
	return flush_children( pagelet );
}


/**
	Moo
*/

dd_result dditemtree::flush_children( ddwebpage& pagelet, int from, int to  )
{
  if( !to || to > _data.size() )
  	to = _data.size();
	
 	for( int i = from; i < to; i++ )
	{
    dd_result result = _data[i]->flush_content( pagelet );
		if( result <= 0 )
			return result;
	}
	return rs_ok;

}

dd_result dditemtree::flush_content( ddwebpage& pagelet, ddstring& target )
{
  // check accessrights
  if( !( get_access() & pagelet.get_user_id().get_access_rights() ) )
		return rs_ok;

	if( !_param.empty() )
		return pagelet.execute_call( _param, *this );

  // hack  
  if( !_value.empty() )
  {
		target.append( dditem::to_string() );
		return rs_ok;
	}
	return flush_children( pagelet, target );
}


/**
	FIX! vereinheitlichen!
*/

dd_result dditemtree::flush_children( ddwebpage& pagelet, ddstring& target, int from, int to )
{
  if( !to || to > _data.size() )
  	to = _data.size();
	
 	for( int i = from; i < to; i++ )
	{
    dd_result result = _data[i]->flush_content( pagelet, target );
		if( result <= 0 )
			return result;
	}
	return rs_ok;
}



