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

    supportware
    Copyright (C) 2001-2010 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 <ddwebrendertag.h>
#include <ddwebfile.h>
#include <ddwebpage.h>
#include <ddwebsite.h>


/**

*/

ddwebrendertag::ddwebrendertag( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddbasename( name ), _parent( parent ), _tagbegin( begin ), _tagend( end )
{
}


/**

*/

ddwebrendertag::~ddwebrendertag()
{
}


/**

*/

ddwebrendertag* ddwebrendertag::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertag( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertag::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{
	// sind wir ein single tag ([nsp]) ? 
	if( _tagend.empty() )
	{
		target += _tagbegin;
		return beg;
	}
	
	// wir sind also ein doppeltag ( [b]moo[/b] ),
	// dann _muss_ das endtag auch vorhanden sein, 
	// sonst ignorieren wir das ganze
	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	// nicht gefunden? dann tag
	// ignorieren und raus!
	if( pos == ddstring::npos )
		return beg;
	
	// ende gefunden: tags ersetzen.
	target += _tagbegin;
	
	// hack: wir 'schmuggeln' unser end-tag direkt in den quellstring
	// und rendern weiter, damit auch innere tags erwischt werden 
	// z.B.:[b][i]moo[/i][/b], eleganter wäre natürlich rekursion .... :-)	
	source.replace( pos, endkey.size(), _tagend );
	
	// und gut ...
	return beg;

}


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

void ddwebrendertag::dump() const
{
	cout <<  "tag: " << get_name() << " : "<< _tagbegin << " : " << _tagend << endl;
}

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

    supportware
    Copyright (C) 2001-2010 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.

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


/**
*/

ddwebrendertagoptend::ddwebrendertagoptend( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertag( name, parent, begin, end )
{

}


/**

*/

ddwebrendertagoptend::~ddwebrendertagoptend()
{
}


/**

*/

ddwebrendertag* ddwebrendertagoptend::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertagoptend( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertagoptend::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{  
	
	// wir sind erstmal ein single tag ([li]) 
	target += _tagbegin;
	
	// vielleicht sind wir ein doppeltag ( li]moo[/li] ),
	// es _kann_ ein endtag vorhanden sein, 
	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	// nicht gefunden? dann  raus!
	if( pos == ddstring::npos )
		return beg;
	
	// ende gefunden: tags ersetzen.
	
	// hack: wir 'schmuggeln' unser end-tag direkt in den quellstring
	// und rendern weiter, damit auch innere tags erwischt werden 
	// z.B.:[b][i]moo[/i][/b], eleganter wäre natürlich rekursion .... :-)	
	source.replace( pos, endkey.size(), _tagend );
	
	// und gut ...
	return beg;

}


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

    supportware
    Copyright (C) 2001-2010 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.

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




/**

*/

ddwebrendertagparam::ddwebrendertagparam( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertag( name, parent, begin, end )
{
	// parameter row erzeugen
	_tagparam.create( begin, "|" );
}


/**

*/

ddwebrendertagparam::~ddwebrendertagparam()
{
}


/**

*/

ddwebrendertag* ddwebrendertagparam::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertagparam( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertagparam::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{	

	// 'beg' zeigt hinter das tag, target geht bis zum tag
	// text[x]*
	// text*
	
	// wir sind also ein doppeltag ( [b]moo[/b] ),
	// dann _muss_ das endtag auch vorhanden sein, 
	// sonst ignorieren wir das ganze
	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	// nicht gefunden? dann tag
	// ignorieren und raus!
	if( pos == ddstring::npos )
		return beg;
	
	// parameter setzen
	_tagparam[1] = param;	
	target += _tagparam.join();
	
	// hack: wir 'schmuggeln' unser end-tag direkt in den quellstring
	// und rendern weiter, damit auch innere tags erwischt werden 
	// z.B.:[b][i]moo[/i][/b], eleganter wäre natürlich rekursion .... :-)	
	source.replace( pos, endkey.size(), _tagend );
	
	// und gut ...
	return beg;

}

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

    supportware
    Copyright (C) 2001-2010 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.

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


/**

*/

ddwebrendertaglist::ddwebrendertaglist( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertag( name, parent, begin, end )
{

}


/**

*/

ddwebrendertaglist::~ddwebrendertaglist()
{
}


/**

*/

ddwebrendertag* ddwebrendertaglist::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertaglist( name, parent, begin, end );
}


/**
SelfHTML:

Für Aufzählungslisten können Sie das Symbol bestimmen, das vor den Listeneinträgen angezeigt wird:
 <ul type="circle"> für nicht ausgefüllte Kreise (circle = Kreis).
 <ul type="disc"> für ausgefüllte Kreise (disc = Scheibe)
 <ul type="square"> für Rechtecke (square = Rechteck).
Für nummerierte Listen können Sie die Art der Nummerierung bestimmen:
 Mit <ol type="I"> werden die Listeneinträge mit I., II., III., IV. usw. nummeriert.
 Mit <ol type="i"> werden die Listeneinträge mit i., ii., iii., iv. usw. nummeriert.
 Mit <ol type="A"> werden die Listeneinträge mit A., B., C. usw. nummeriert.
 Mit <ol type="a"> werden die Listeneinträge mit a., b., c. usw. nummeriert.
Mit start innerhalb des einleitenden Tags von <ol> können Sie einen beliebigen Startwert setzen, z.B. <ol start="7">. Die Nummerierung beginnt dann bei 7.
Mit value innerhalb des Tags von <li> in einer nummerierten Liste können Sie den Startwert beliebig neu setzen, z.B. auf <li value="15">. Die Nummerierung fährt dann bei 15 fort.


Unterstützt werden die in der SN-Hilfe angegebenen Formate:

[list]		: bobbel
[list=1]	: numeriert
[list=i]	: römisch klein
[list=I]	: römisch groß
[list=a]	: buchstaben klein
[list=A]	: buchstaben groß

Der Hack an det janze ist, das mal <ul>, mal <ol>s generiert werden müssen
*/

size_t ddwebrendertaglist::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{	

	// das endtag _muss auch vorhanden sein, 
	// sonst ignorieren wir das ganze
 	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	// nicht gefunden? dann tag
	// ignorieren und raus!
	if( pos == ddstring::npos )
		return beg;

	// je nach parameter sind wir ein <ul> oder ein <ol>:
	ddstring begtag = _tagbegin;
	ddstring endtag = _tagend;
	if( param == "1" || param == "i" || param == "I" || param == "a" || param == "A" )
	{
	 	begtag = "<ol type='" + param + "'>";
	 	endtag = "</ol>";
	}
	
	/*
		Neu: Unordered Lists:
		> Hi,
		> Entsprechend den SN-Standards wäre das dann sowas wie :
		> [list=c]
		> [list=d]
		> [list=s]		
	*/
	
	else if( param == "c" || param == "d" || param == "s" )
	{
	 	ddstring lparam = ( param == "c" ? "circle" : param == "d" ? "disc" : "square" );
	 	begtag = "<ul type='" + lparam + "'>";
	 	endtag = "</ul>";
	}

	// ende gefunden: tags ersetzen.
	target += begtag;
	
	// hack: wir 'schmuggeln' unser end-tag direkt in den quellstring
	// und rendern weiter, damit auch innere tags erwischt werden 
	// z.B.:[b][i]moo[/i][/b], eleganter wäre natürlich rekursion .... :-)	
	source.replace( pos, endkey.size(), endtag );
	
	// und gut ...
	return beg;
	
	
}


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

    supportware
    Copyright (C) 2001-2010 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.

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


/**

*/

ddwebrendertagimage::ddwebrendertagimage( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertagparam( name, parent, begin, end )
{
	_imagevotes.create( "<p class='vote' style='width:|1|px;'>\n\t<a href='|3|' class='image-not-ok'>Bild melden</a>\n\t<a href='|5|' class='image-ok'>Bild ok</a>|7|", "|" );
}


/**

*/

ddwebrendertagimage::~ddwebrendertagimage()
{
}


/**

*/

ddwebrendertag* ddwebrendertagimage::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertagimage( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertagimage::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{	

	// 'beg' zeigt hinter das tag, target geht bis zum tag
	// text[x]*
	// text*
	
	// wir sind also ein doppeltag ( [b]moo[/b] ),
	// dann _muss_ das endtag auch vorhanden sein, 
	// sonst ignorieren wir das ganze
	
	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	// nicht gefunden? dann tag
	// ignorieren und raus!
	if( pos == ddstring::npos )
		return beg;
		
	ddstring realimage = source.substr( beg, pos-beg );

	// parameter setzen: externe links sollen zugelassen sein,
	// daher den internen pfad nur bei internen bildern setzen
	
	//ddstring picpart = row["id_parent"] + "/"; 
	ddstring picpart = row["id"] + "/"; 
	// wild: wenn der bildname mit DDUSERPICPREFIX ( == memimg- ) anfängt,
	// ist es ein user bild, sonst gehörts zu einem artikel
	ddstring pathpart = param.contains( DDUSERPICPREFIX ) ?  "/memberimage/" : "/articleimage/" ;
	
	// die bild-url
	if( param.contains( "http" ) )
		_tagparam[1] = param;
	else
		_tagparam[1] = pathpart + picpart + param;
		
	
	// der bild-title: dateiname ohne endung
	// neues tag format: 	<a href='|1|' target='_blank'><img title='|2|' alt='|4|' src='/articleimage/,' border='0'></a>
	// 'alt' == 'title', und zwar bildname wie gehabt, aber ohne _ und -
	ddstring title = param.trim_pattern( "." );
	
	// hässlich: eventuelle größenangaben absäbeln
	size_t dot = title.rfind( "-" );
	if( dot != ddstring::npos )
	{
		ddstring msize = title.substr( dot+1 );						
		if( msize == "40" || msize == "80" 
			|| msize == "200" || msize == "470" )
			title = title.substr( 0, dot );
	}
	
	title.blank_all_of( "-_" );	
	_tagparam[3] = title;
	_tagparam[5] = title;
	
	ddstring result = _tagparam.join() + pathpart + picpart;
	ddstring tagend = _tagend;
						
	ddwebfilemanager& mgr = pagelet.get_site().get_file_manager();
	
	// wenn das bild unter verwaltung steht 
	// und noch nicht freigegeben ist
	if( mgr.contains_key( param )  )
	{
		
	
		// hässlich: eventuelle größenangaben absäbeln
		size_t dash = realimage.rfind( "-" );
		ddstring xsize;		
		bool big_image = true;
		if( dash != ddstring::npos )
		{
			xsize = realimage.substr( dash+1 );						
			xsize = xsize.trim_pattern( "." );	
	
			if( xsize == "40" || xsize == "80"  /* xsize.empty() || xsize == "200" || xsize == "470" */ )
				big_image = false;
		}

		ddwebfile& entry = mgr.get_entry( param );
		if( entry.is_draft() && big_image )
		{
			//"<p class='vote' style='width:|1|px;'><a href='|3|' class='image-not-ok'>Bild melden</a><a href='|5|' class='image-ok'>Bild ok</a>|7|"
		
			//_imagevotes[1] = !image_resized ? entry.get_media_width() : xsize ;
			_imagevotes[1] =  xsize ;
			//_imagevotes[1] = entry.get_media_width();
			_imagevotes[3] = "?sx_action=on_image_vote_bad&sn_key=" + param;
			_imagevotes[5] = "?sx_action=on_image_vote_good&sn_key=" + param;
			_imagevotes[7] = result;
			
			result = _imagevotes.join() ;
			
			// hack: das endtag aufbrezeln
			tagend += "\n</p>"; 
		}
	}

	
	
	target += result;
	
	// hack: wir 'schmuggeln' unser end-tag direkt in den quellstring
	// und rendern weiter, damit auch innere tags erwischt werden 
	// z.B.:[b][i]moo[/i][/b], eleganter wäre natürlich rekursion .... :-)	
	source.replace( pos, endkey.size(), tagend );
	
	// und gut ...
	return beg;


}


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

    supportware
    Copyright (C) 2001-2010 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.

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


/**

*/

ddwebrendertagvideo::ddwebrendertagvideo( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertagparam( name, parent, begin, end )
{

}


/**

*/

ddwebrendertagvideo::~ddwebrendertagvideo()
{
}


/**

*/

ddwebrendertag* ddwebrendertagvideo::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertagvideo( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertagvideo::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{	

	/*
	
	Fieses Teil:
	
	video	 	 = "video,<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' width='|1|' height='|2|' id='|3|' name='|4|'>
						<param name='movie' value='/video/player-viral.swf'>
						<param name='allowfullscreen' value='true'>
						<param name='allowscriptaccess' value='always'>
						<param name='play' value='true'>
						<param name='wmode' value='transparent'>
						<param name='flashvars' value='file=|5|&|autostart=true|'>
						<embed
						type='application/x-shockwave-flash'
						id='single2'
						name='single2'
						src='/video/player-viral.swf'
						width='|7|'
						height='|8|'
						bgcolor='undefined'
						allowscriptaccess='always'
						allowfullscreen='true'
						wmode='transparent'
						flashvars='file=|9|&|autostart=true|'
						/>
						</object>";

	*/
	
	// 'beg' zeigt hinter das tag, target geht bis zum tag
	// text[x]*
	// text*
	
	// wir sind also ein doppeltag ( [b]moo[/b] ),
	// dann _muss_ das endtag auch vorhanden sein, 
	// sonst ignorieren wir das ganze
	
	/*
	
	brauchen wir ein end-tag?
	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	
	// nicht gefunden? dann tag
	// ignorieren und raus!
	if( pos == ddstring::npos )
		return beg;
	*/
	
	// parameterliste bearbeiten:
	// das tag geht so: [video=film;breite;höhe[;bild]] 
	// Das Bild ist optional, wenn vorhanden gibbet kein autostart,
	// sonst schon.
	// z.b. [video=testvideo.mp4;300;300;moo.jpg]
	
	ddstringrow plist( param, ";" );
	// mindesten 3 params müssen vorhanden sein
	if( plist.size() < 3 )
		return beg;
	
	// videopfad bauen
	ddstring pathpart = "/articleimage/" +	row["id"] + "/";
	ddstring vidpart  = pathpart + plist[0]; 
	ddstring picpart;
	if( plist.size() == 4 )
	  picpart = "image=" + pathpart + plist[3]; 
	
	/*
	enum dd_videotag_fields
	{
		videotag_width1			= 1,
		videotag_height1		= 3,
		videotag_id1				= 5,
		videotag_name1 			= 7,
		videotag_file1			= 9,
		videotag_img1				= 11,
		videotag_id2				= 13,
		videotag_name2 			= 15,		
		videotag_width2			= 17,
		videotag_height2		= 19,
		videotag_file2			= 21,
		videotag_img2				= 23,
	};
	
	enum dd_videoparam_fields
	{
		videoparam_file			= 0,
		videoparam_width		= 1,
		videoparam_height		= 2,
		videoparam_image		= 3,
	};
	
	*/
	
	// ... und zusammenbasteln
	_tagparam[videotag_width1] 	= _tagparam[videotag_width2]  = plist[videoparam_width]; 			
	_tagparam[videotag_height1] = _tagparam[videotag_height2]	= plist[videoparam_height];
	_tagparam[videotag_id1]  		= _tagparam[videotag_name1]		= plist[videoparam_file];
	_tagparam[videotag_id2]  		= _tagparam[videotag_name2]		= plist[videoparam_file];
	// das einzig wichtige ...
	_tagparam[videotag_file1] 	= _tagparam[videotag_file2] 	= vidpart;
	// wenn kein bild vorhanden ist, wird autostart 'true' gesetzt.
	if( picpart.empty() )
		picpart = "autostart=true";
	_tagparam[videotag_img1]	 	= _tagparam[videotag_img2] 		= picpart;
		
	target += _tagparam.join();
		
	// und gut ...
	return beg;


}




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

    supportware
    Copyright (C) 2001-2010 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.

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


/**

*/

ddwebrendertagyoutube::ddwebrendertagyoutube( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertagparam( name, parent, begin, end )
{

}


/**

*/

ddwebrendertagyoutube::~ddwebrendertagyoutube()
{
}


/**

*/

ddwebrendertag* ddwebrendertagyoutube::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertagyoutube( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertagyoutube::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{	

	/*
	
	Fieses Teil:
	
						
	youtube	=	"<object width='425' height='344'><param name='movie' value='http://www.youtube.com/v/l5Y2Y2UISAY&hl=de&fs=1'></param>
						<param name='allowFullScreen' value='true'></param>
						<param name='allowscriptaccess' value='always'></param>
						<embed 
							src='http://www.youtube.com/v/l5Y2Y2UISAY&hl=de&fs=1' 
							type='application/x-shockwave-flash' 
							allowscriptaccess='always' 
							allowfullscreen='true' 
							width='425' 
							height='344'>
						</embed>
						</object>";
	

	*/
	
	// 'beg' zeigt hinter das tag, target geht bis zum tag
	// text[x]*
	// text*
	
	// wir sind also ein doppeltag ( [b]moo[/b] ),
	// dann _muss_ das endtag auch vorhanden sein, 
	// sonst ignorieren wir das ganze
	
	/*
	
	brauchen wir ein end-tag?
	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	
	// nicht gefunden? dann tag
	// ignorieren und raus!
	if( pos == ddstring::npos )
		return beg;
	*/
	
	// parameterliste bearbeiten:
	// das tag geht so: [video=film;breite;höhe[;bild]] 
	// Das Bild ist optional, wenn vorhanden gibbet kein autostart,
	// sonst schon.
	// z.b. [video=testvideo.mp4;300;300;moo.jpg]
	
	ddstring params = param;
	params.replace_all( "&amp;", "&" );
	ddstringrow plist( params, ";" );
	if( plist.size() < 1 )
		return beg;
	
	_tagparam[1]  		= _tagparam[3]		= plist[0];	
	target += _tagparam.join();
		
	// und gut ...
	return beg;
	
	
	/*
	ddstringrow plist( param, ";" );
	// mindesten 3 params müssen vorhanden sein
	if( plist.size() < 3 )
		return beg;
	
	// videopfad bauen
	ddstring pathpart = "/articleimage/" +	row["id"] + "/";
	ddstring vidpart  = pathpart + plist[0]; 
	ddstring picpart;
	if( plist.size() == 4 )
	  picpart = "image=" + pathpart + plist[3]; 
	*/
	
	/*
	enum dd_videotag_fields
	{
		videotag_width1			= 1,
		videotag_height1		= 3,
		videotag_id1				= 5,
		videotag_name1 			= 7,
		videotag_file1			= 9,
		videotag_img1				= 11,
		videotag_id2				= 13,
		videotag_name2 			= 15,		
		videotag_width2			= 17,
		videotag_height2		= 19,
		videotag_file2			= 21,
		videotag_img2				= 23,
	};
	
	enum dd_videoparam_fields
	{
		videoparam_file			= 0,
		videoparam_width		= 1,
		videoparam_height		= 2,
		videoparam_image		= 3,
	};
	
	*/
	
	/*
	// ... und zusammenbasteln
	_tagparam[videotag_width1] 	= _tagparam[videotag_width2]  = plist[videoparam_width]; 			
	_tagparam[videotag_height1] = _tagparam[videotag_height2]	= plist[videoparam_height];
	_tagparam[videotag_id1]  		= _tagparam[videotag_name1]		= plist[videoparam_file];
	_tagparam[videotag_id2]  		= _tagparam[videotag_name2]		= plist[videoparam_file];
	// das einzig wichtige ...
	_tagparam[videotag_file1] 	= _tagparam[videotag_file2] 	= vidpart;
	// wenn kein bild vorhanden ist, wird autostart 'true' gesetzt.
	if( picpart.empty() )
		picpart = "autostart=true";
	_tagparam[videotag_img1]	 	= _tagparam[videotag_img2] 		= picpart;
		
	target += _tagparam.join();
		
	// und gut ...
	return beg;
*/

}


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

    supportware
    Copyright (C) 2001-2010 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.

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


/**
*/

ddwebrendertagurl::ddwebrendertagurl( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertagparam( name, parent, begin, end )
{

}


/**

*/

ddwebrendertagurl::~ddwebrendertagurl()
{
}


/**

*/

ddwebrendertag* ddwebrendertagurl::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertagurl( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertagurl::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{
	
	
	// das endtag _muss auch vorhanden sein, 
	// sonst ignorieren wir das ganze
	
	// das bedient url & xurl
	ddstring endkey = "[/url]";
	size_t pos = source.find( endkey, beg );
	// nicht gefunden? dann tag
	// ignorieren und raus!
	if( pos == ddstring::npos )
		return beg;
	
	// so, jetzt geht der url-krampf los...
	// gibbet einen url-parameter?
	// sonst ist der linktext die url
	
	ddstring linktext = source.substr( beg, pos-beg );
	ddstring title, newparam = param;
	// optionalen link-title aus dem parameter extrahieren
	param.split( DDLINKSEPARATOR, newparam, title );
	ddstring url = newparam.empty() ? linktext : newparam;
	
	// urls absolutieren, vormals prepare_link
	if( !url.contains( "https://" ) 
	 && !url.contains( "http://" )
	 && !url.contains( "ftp://" ) )
	 	url =  "http://" + url;
	
	// linkziel setzten:
	// <a href='|1|' class='sn_cont' target=_new |2|>
	_tagparam[1] = url;
	_tagparam[3] = title;
	
	// nofollow ermitteln
	bool nofollow = _parent->get_no_follow_flag();
	_tagparam[5] = nofollow ? " rel='nofollow'" : "" ;

	target += _tagparam.join();
	
	// hack: wir 'schmuggeln' unser end-tag direkt in den quellstring
	// und rendern weiter, damit auch innere tags erwischt werden 
	// z.B.:[b][i]moo[/i][/b], eleganter wäre natürlich rekursion .... :-)	
	
	source.replace( pos, endkey.size(), _tagend );
	
	// der linktext kann auch manipuliert werden, also müssen wir
	// den auch dem quellstring unterjubeln.
	
	if( _parent->get_chop_flag() && linktext.size() > 70 )
		source.replace( beg, linktext.size(), linktext.substr( 0, 67 ) + "..." ); 
	
	// und gut ...
	return beg;

}



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

    supportware
    Copyright (C) 2001-2010 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.

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


/**
*/

ddwebrendertagcode::ddwebrendertagcode( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
:	ddwebrendertag( name, parent, begin, end )
{

}


/**

*/

ddwebrendertagcode::~ddwebrendertagcode()
{
}


/**

*/

ddwebrendertag* ddwebrendertagcode::create( const ddstring& name, ddwebrendertagblock* parent, const ddstring& begin, const ddstring& end )
{
	return new ddwebrendertagcode( name, parent, begin, end );
}


/**

*/

size_t ddwebrendertagcode::render( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, const ddstring& param, size_t beg, ddstring& target )
{  
	
	// DAS IST BUGGY!
	
	// 'beg' zeigt hinter das tag, target geht bis zum tag
	// text[x]*
	// text*
	
	// wir sind also ein doppeltag ( [b]moo[/b] ),
	// dann _muss_ das endtag auch vorhanden sein, 
	// sonst ignorieren wir das ganze
	
	ddstring endkey = "[/" + rawkey + "]";
	size_t pos = source.find( endkey, beg );
	// nicht gefunden? dann tag
	// ignorieren und raus!
		
	// eventuelle parameter choppen
	if( pos == ddstring::npos )
		return beg;
	
	// ende gefunden: tags ersetzen.
	target += _tagbegin;	
	// innerhalb des [code] tags wird nix ersetzt,
	// also alles zwischen den tags übernehmen
	target += source.substr( beg, pos-beg );
	// ende dranhängen
	target += _tagend;	
	// weiter ...
	pos += endkey.size();
	
	// und gut ...
	return pos;


}


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

    supportware
    Copyright (C) 2001-2010 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.

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


/**
*/

ddwebrendertagfactory::ddwebrendertagfactory()
{

	// speziaisierte tags mit eigenen renderern
	add_by_key( "url", 		new ddwebrendertagurl  		( "name", 0, "dummy", "dummy" ) );
	add_by_key( "xurl",		new ddwebrendertagurl  		( "name", 0, "dummy", "dummy" ) );
	add_by_key( "code", 	new ddwebrendertagcode 		( "name", 0, "dummy", "dummy" ) );
	add_by_key( "list", 	new ddwebrendertaglist 		( "name", 0, "dummy", "dummy" ) );
	
	// tag mit optionalem Ende
	// geht nich wg. config file syntax
	//add_by_key( "*", 		new ddwebrendertagoptend( "name", 0, "dummy", "dummy" ) );
	add_by_key( "tag20", 	new ddwebrendertagoptend	( "name", 0, "dummy", "dummy" ) );

	add_by_key( "img",  	new ddwebrendertagimage		( "name", 0, "dummy", "dummy" ) );
	add_by_key( "imgr", 	new ddwebrendertagimage		( "name", 0, "dummy", "dummy" ) );
	add_by_key( "imgl", 	new ddwebrendertagimage		( "name", 0, "dummy", "dummy" ) );
	// Nein! das geht ohne ID und ist daher ein 'normaler' param-tag
	//add_by_key( "pic",  new ddwebrendertagimage( 0, "dummy", "dummy" ) );
	
	add_by_key( "video",  new ddwebrendertagvideo		( "name", 0, "dummy", "dummy" ) );
	add_by_key( "youtube",new ddwebrendertagyoutube	( "name", 0, "dummy", "dummy" ) );
	//...

}


/**

*/

ddwebrendertagfactory::~ddwebrendertagfactory()
{
}


/**

*/

ddwebrendertag* ddwebrendertagfactory::create_tag( const ddstring& name, ddwebrendertagblock* parent, const ddstring& tagdata, ddstring& key )
{
	
	// tagdaten erzeugen
	ddstringrow data( tagdata, ",", 3 );
	ddwebrendertag* result;
	
	// format: tag20 = "*,<li>,</li>";
	// also: <name> = "<key>,"<anfang>,[<ende>]";
	// bzw. parameterbehaftet: <name> = "<key>,"<anfang=|1|...>,[<ende>]";
	
	// gibts es ein specialtag (url,code ... ) ?
	if( contains_key( name ) )
	{
		result = (*this).get_entry( name ).create( name, parent, data[1], data[2] );
	}
	else
	{
		// gibts parameter?
		bool has_param = ( data[1].contains( '|') );	
		if( has_param )
			result = new ddwebrendertagparam( name, parent, data[1], data[2] );
		else
			result = new ddwebrendertag( name, parent, data[1], data[2] );			
	}
	
	// den key übergeben
	key = data[0];
	
	return result;
}


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

    supportware
    Copyright (C) 2001-2010 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.

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


/**
	Default constructor.
*/

ddwebrendertagblock::ddwebrendertagblock( const ddstring& name, bool nofollow, bool chopflag  )
:	ddbasename( name ), _nofollow( nofollow ), _chopflag( chopflag )
{

}
	
	
/**
	Destructor.
*/

ddwebrendertagblock::~ddwebrendertagblock()
{

}



/**
	Einen BBCode-Block rendern
	@see translate_tag.
*/

//render( dddatastaterow& src, const ddstring& value, ddstring& target );
void ddwebrendertagblock::render( ddwebpage& pagelet, dditem& item, dddatastaterow& row, const ddstring& src )
{
  size_t beg=0, end1=0, end2=0, end3=0;
	// ent-konsten
	ddstring source = src;
	ddstring target;

	// es ergeben sich folgende fallunterscheidungen:
	// 1. ............... 	kein tag
	// 2. ........[......		offenes tag
	// 3. ........[].....   leeres tag
	// 4. ........[tag]..   na also!
	
	while( beg < source.size() )
	{
 		end1 = source.find( '[', beg );
		
		// Fall 1: anfang nicht gefunden
		if( end1 == ddstring::npos )
		{
			// Fülleintrag
			target += source.substr( beg );
			break;
		}
		
		// anfang gefunden -> ende suchen
		end2 = end1+1;
		end3 = source.find( ']', end2 );
		
		// Fall 2: ende nicht gefunden, 
		// dann brauch man eh nicht weitersuchen
		if( end3 == ddstring::npos  )
		{
			// Fülleintrag
			target += source.substr( beg );
			break;
		}

		// ende auch gefunden.
		// Fall 3: Ist der key-string leer?
		if( end2 == end3 )
		{
			end3++;
			// Fülleintrag
			target += source.substr( beg, end3-beg );
			beg = end3;
			continue;
		}
		
		// Fall 4: wir haben ein tag gefunden
		ddstring key = source.substr( end2,end3-end2 );
		// Fülleintrag
		target += source.substr( beg, end1-beg );	
		beg = render_tag( pagelet, row, source, key, ++end3, target );
   
  } // while
  
			
	//???
  //target.replace_all( "\t", "&nbsp;&nbsp;&nbsp;" );
	target.replace_all( "\r\n", "<br>" );
	
	// mörderhack
	beg = 0;
	while( re_replace_br( target, beg ) )
		;
		
	item.from_string( target );
  

}


/**
	Einen einzelnes BBCode-Tag übersetzen.
*/

size_t ddwebrendertagblock::render_tag( ddwebpage& pagelet, dddatastaterow& row, ddstring& source, const ddstring& rawkey, size_t beg, ddstring& target )
{
	// 'beg' zeigt hinter das tag, target geht bis zum tag
	// text[x]*
	// text*
	
	// eventuelle parameter choppen
	ddstring key, param;
	size_t pos = rawkey.find( '=' );
	// parameter gefunden?
	if( pos != ddstring::npos )
	{
		key 	 = rawkey.substr( 0, pos );
		param  = rawkey.substr( pos+1 );
	}
	else
	{
		key = rawkey;
	}
	
	//gibt es das tag überhaupt?
	if( !contains_key( key ) )
	{
		// keep unknown keys
		target += "["+key;
		// param?
		if( !param.empty() )
			target += "=" + param;
		target += +"]";
		// und weitersuchen
		return beg;
	}
	
	// es gibt das tag, also rendern
	return get_entry( key.to_lower() ).render( pagelet, row, source, key, param, beg, target );
		
}
	

/**
	cyc proudly presents: der gipfel des brainfucks: re_replace_br 
*/

bool ddwebrendertagblock::re_replace_br( ddstring& target, size_t& p1 )
{
	p1 = target.find( "<pre>", p1 );
	// kein anfang	
	if( p1 == ddstring::npos )
		return false;
	// anfang da, ende suchen
	p1 += 5;
	size_t p2 = target.find( "</pre>", p1 );
	// kein ende?
	if( p2 == ddstring::npos )
		return false;
	// ende gefunden
	ddstring sub = target.substr( p1, p2-p1 );
	sub.replace_all( "<br>", "\r\n" );
	target.replace( p1, p2-p1, sub );
	p1 = p2;
	return true;
}



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

    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.

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


/**
	Standard Constructor.
*/

ddwebrendertagblockmap::ddwebrendertagblockmap()
{

}


/**
	Destructor.
*/

ddwebrendertagblockmap::~ddwebrendertagblockmap()
{

}
	

/**
	Tabellen einlesen.
*/

void ddwebrendertagblockmap::init_tag_blocks( ddconfig& config )
{
	
	// setup tag blocks	
	for( int i=0; i<config.size(); ++i )
	{
		// these tables are private property of a pagelet.
		if( config[i].get_type() != "tagblock" )
			continue;
		// setup data table
		add_tag_block( config, config[i] );
	}
	
}


/**
	Tagblock erzeugen und mit den Tags aus der configsection füllen. 
*/

void ddwebrendertagblockmap::add_tag_block( ddconfig& config, ddconfigsection& section )
{
	
	bool nofollow = section.get_bool( "nofollow", true );
	bool choptext = section.get_bool( "choptext", true );
	ddwebrendertagblock* tagblock = new ddwebrendertagblock( section.get_name(), nofollow, choptext );
	add_by_key( section.get_name(), tagblock );	
	
	// rausfinden, ob geerbt wird.
	if( section.contains_key( "extends" ) )
	{
		// lade die section (=tagblock), auf die der key 'extends' zeigt
		// Achtung: nur die Einträge aus configsection laden reicht nicht,
		// da die Quellsection selber von Einträge erbt, die hier dann
		// fehlen. Also: oldschool: Ergebnisse holen.
		
		ddwebrendertagblock& oldblock = get_entry( section["extends"] );
		for( int i = 0; i < oldblock.size(); ++i )
			// PFUSCH: pointer copy -> doppelte destruction
			tagblock->add_by_key( oldblock.key_of( i ), oldblock[i] );
	
	}
	
	// hier wird mit verschiedenen schlüsseln gearbeitet:
	// tag0="*,moo,koo";
	// tag0 ist der erzeugerkey für die factory,
	// '*' ist der bbcode key, der im textblock gesucht und ersetzt wird.
	
	for( int i = 0; i < section.size(); ++i )
	{
		const ddstring& name = section.key_of( i );
		if( name == "nofollow" || name == "choptext" )
			continue;
			
		ddstring tagkey;
		ddwebrendertag* tag = _tagfactory.create_tag( name, tagblock, section[i], tagkey );
	
		// das ist kein Fehler, denn über vererbung können tags
		// überschrieben werden.
		
		// Achtung! Neu! geerbte tags sind pointer-copies (siehe oben) und 
		// dürfen _nich_t deletet werden!
		/*
		if( tagblock->contains_key( tagkey ) )
			tagblock->replace( tagkey, tag );
		else
		*/
		
		tagblock->add_by_key( tagkey, tag );
	
	}

}


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

void ddwebrendertagblock::dump() const
{
	cout << "tagblock: "  << get_name() << endl;
	for( int i=0; i<size(); ++i )
		(*this)[i]->dump();
}


/*
	s01 = "*";
	s02 = ":)";
  s03 = ";)";
  s04 = ":D";
  s05 = ";D";
  s06 = "}:(";
  s07 = ":?";
  s08 = "8)";
  s09 = ":o";
  s10 = "::)";
  s11 = ":P";
  s12 = ":X";
  s13 = ":[";
  s14 = ":*";
  s15 = ":/";
  s16 = ":(";
  s17 = ";(";
  
  	//tag16 = "list=1"] = "<ol type='1'>";
	//tag17 = "list=a"] = "<ol type='a'>";
	//tag18 = "list=A"] = "<ol type='A'>";	
	tag19 = "/list"] = "";

  */
	
