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

    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 <dditemset.h>
#include <dditemtree.h>
#include <dditemlink.h>

dditemset::dditemset()
{
	
}


dditemset::~dditemset()
{
  throw runtime_error( "FIX ME: dditemset::~dditemset()" );
	/*
	dditemset::iterator pos = _factory.begin();
	for( ; pos != _factory.end(); ++pos )
		delete (*pos).second;
	*/
}


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

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


void dditemset::init_items( const ddstring& basepath, const ddstring& sitepath )
{
  _dirinfo.load_files( basepath, ".html", true );
	if( !sitepath.empty() )
	  _dirinfo.load_files( sitepath, ".html", true );
	
	size_t max = _dirinfo.size();
	if( !max )
		return;

  //_dirinfo.dump();
  
  for( size_t i=0; i<max; ++i )
  	create_from_file( *this, _dirinfo[i].get_file_name(), _dirinfo[i] );
   
}


void dditemset::create_from_file( dditemtree& current, const ddstring& key, ddioinfo& file )
{
   // Create entry
   dditemtree* result = new dditemtree( key );
   current.add_child( result );
   create_from_string( *result, file.get_file_content() );
}


void dditemset::create_from_string( dditemtree& current, const ddstring& src )
{

	size_t beg=0, end1=0, end2=0, end3=0;

	while ( beg < src.size() )
	{
		end1 = src.find( DDPATBEG, beg );
		// anfang gefunden -> ende suchen
		if( end1 != ddstring::npos )
		{
			end2 = end1+5;
			end3 = src.find( DDPATEND, end2 );
			// ende auch gefunden.
			if( end3 != ddstring::npos  )
			{
				// Fülleintrag
			  current.add_child( "", src.substr( beg, end1-beg ) );
        // Ist der key-string nicht leer?
        if( end2 != end3 )
        {
					end3 += 3;
					ddstring key = src.substr( end2,end3-end2-3 );
          create_from_key( current, key, src, end3 );
				}
        else
        {
					end3 += 3;
          // Fülleintrag
          current.add_child( "", src.substr(end1,end3-end1) );
        }
   			beg = end3;

			}
			else		// ende nicht gefunden
			{
				// Fülleintrag
				current.add_child( "", src.substr( beg, end2-beg )  );
				beg = end2;
			}

		}
		// anfang nicht gefunden
		else
		{
			// Fülleintrag
			current.add_child( "", src.substr( beg ) );
			break;
		}

	} // while

}


bool dditemset::create_from_key( dditemtree& current, const ddstring& key, const ddstring& src, size_t& end )
{

	ddstringrow tmp( key, ":" ) ;

  if( tmp.size() 	== 0 )
		return false;

  // es wird geerbt
  if( tmp.size() == 2 && tmp[0] == "extends" )
  	return create_from_extend( current, tmp[1] );
   
  // es ist ein tree...
  if( tmp.size() > 2 && tmp[1] == "dp_item" )
  {
		
		int i = _dirinfo.index_of( tmp[2] );
		if( i<0 )
	 		return log_error( "dditemset::create_from_key: not found --" + tmp[0] + "-- : --" + tmp[2] + "--" );
	  if( _dirinfo[i].load_file_content()<0 )
      return log_error( "dditemset::create_from_file: not found" + _dirinfo[i].get_full_name() );

    // sehr fragwürdig!
    dditemtree* newresult = new dditemtree( tmp[0] );
    _factory.config_item( tmp, newresult );
    current.add_child( newresult );
    create_from_string( *newresult, _dirinfo[i].get_file_content() );
    return true;
   }
 
  // alle anderen typen...
	bool is_section = false;
  dditem* newitem = _factory.create_item( *this, tmp, is_section );
	if(!newitem)
		return false;   
	current.add_child( newitem );
	
	if( !is_section )
		return true;
	
  // es ist eine section: section ende finden
 	ddstring seek = ddstring(DDPATBEG)+"/"+tmp[0]+DDPATEND;
 	size_t sec = src.find( seek, end );
 	// gefunden
 	if( sec != ddstring::npos  )
 	{
 		  create_from_string( (dditemtree&) *newitem, src.substr( end, sec-end ) );
 		  end = sec+seek.size();
 	}
 	else
 	{
 		cout << "dditemset::create_by_key: section end not found:" <<  seek << end;
 	}
  return true;
}


bool dditemset::create_from_extend( dditemtree& current, const ddstring& key )
{
	// elternobject gibts noch nicht
  if( index_of( key ) < 0 )
  {
    // gibts die elterndatei?
    int index = _dirinfo.index_of( key );
    // elternobjekt erzeugen
  	if( index>-1 )
  		create_from_file( *this, key, _dirinfo[index] );
  } // elternobject laden

  // elternobject müsste es jetzt geben
  int i1 = index_of( key );
  if( i1 >=0 )
  {
    dditem& parent = (*this)[ i1 ];
    // elternobject entry-wise klonen.
  	for( size_t i=0; i<parent.size(); ++i )
  		current.add_child( parent[i].clone() );
  }
  return true;
}




