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

    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.

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


#ifndef DDWEBPAGE_H
#define DDWEBPAGE_H


#include <dditemtree.h>
#include <ddwebrequest.h>
#include <ddstringrow.h>
#include <ddthreadrunnable.h>
#include <dddatatable.h>
#include <ddwebconnection.h>
#include <ddthreadmutex.h>
#include <dddataconnection.h>

class ddwebsite;
class ddiobuffer;
class ddwebpage;
class ddwebview;
class ddusermanager;
class ddusersessionmanager;
class ddmailmanager;
class dduserid;
class ddwebcgi;
class ddwebgroupmgr;

/// ddwebpagecall: ein Eintrag in der Callbacktabelle
/**

	Callbacks sind die Generatorfunktionen, die von aussen oder beim
	Rendern aufgerufen werden.
		
*/


typedef dd_result (ddwebpage:: *ddmemptr)( dditem& );

struct ddwebpagecall
{
	ddmemptr	memptr;
	ddstring	itemkey;
	size_t 		access;
	size_t	 	pathlen;
		
	ddwebpagecall()
	: memptr( 0 ), itemkey( "--" ), access( 0 ), pathlen( 1 )
	{

	}
	
	ddwebpagecall( ddmemptr aptr, const ddstring& akey, size_t axr, size_t apathlen=1 )
	: memptr( aptr ), itemkey( akey ), access( axr ), pathlen( apathlen )
	{
		
	}
		
};

typedef map<ddstring,ddwebpagecall> ddwebpagecallmap;


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

    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.

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


/// Eintrag in der Request-Queue eines Pagelets
/**

	Eintrag in der Request-Queue eines Pagelets. 
	Aus pageletproxy übernommen.	
	
*/

struct ddwebpagerequest
{
	ddwebpagerequest()
	: connection( 0 ), userid( 0 ), starttime( 0 )
	{
	
	}
	
	ddwebpagerequest( ddwebconnection* aconnection, dduserid* auserid )
	: connection( aconnection ), userid( auserid )
	{
		starttime = ::time( 0 );
	}
	
	ddwebconnection* 	connection;
	dduserid*				 	userid;
	time_t						starttime;

};


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

    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.

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


/// ddwebcontext: katzentisch für hässliche, kleine membervariablen
/**
	Die ganzen pickeligen kleinen membervariablen und ihre getter und setter
	wurden  ausgelagert. Das ganze ist public, kann also auch von
	renderern, blocks etc. benutzt werden.
*/

struct ddwebcontext
{
	
	ddstring  	id, idgrp; 					// pfadargumente: groups/23 bzw. thread/342525
	int					numrows; 						// die daten für den navi
	int					navifrom;						// die daten für den navi
	int					navito;  						// die daten für den navi
	int					navipage;						// die aktuelle Seite
	ddstring		navilinkbase;				// die linkbasis, etwa 'recipes' bei 'recipes/4'
  int					itemspp;						// items per page?
	ddstring		subject;
	ddstring 		pagetitle;					// na was
  ddstring 		pagetitlestatic;		// na was
  ddstring  	contenttype;				// meistens text/html, wird in den rss-seiten geändert
  ddstring  	pagetype;						// news, faqs etc.
  size_t			errorcode;
  ddstring		errortext;
  
  ddwebcontext()
  {
  	reset(); 		
  }
  
  void reset()
	{
		id 						= subject = "";
		numrows     	= navifrom = navito = -1;
		navipage 			= 0;
		itemspp 			= 0;	
		idgrp 				= "1"; // dummy grp ist default ??
  	contenttype 	= "text/html";	
		errorcode 		= ddwebresponse::ret_500_internal_server_error;
  	errortext 		= "Unknown Error";
	}

};


/// Ein ddwebpage entspricht in etwa dem, was in java ein servlet ist.
/**
	
	Ein ddwebpage entspricht in etwa dem, was in java ein servlet ist: Ein Generator
	für eine Seite (/home) oder zusammenhängende Seiten eines bestimmten Seitentyps,
	z.B. faqs
	Im Rahmen der allgemeinen Aufräuminitiative wurde 'pageletproxy' wegrationalisiert
	und mit 'pagelet' zusammengelegt.
	(ddwebpageproxy: worker thread der einen seitengenerator steuert.)
	
	Enthält allerlei obskure Zusatzfunktionen, die nur im SN vorkommen, etwa
	pagerboxen etc. FIX! Eigentlich deprecated, da die Zusatzfunktionen in Block-Renderer 
	ausgelagert werden sollen.
	
*/

typedef deque<ddwebpagerequest> ddwebpagerequestqueue;

class ddwebpage : public ddthreadrunnable
{

public: 

	enum dd_redirect_type
	{
		ret_301_moved_permanently=1,
		ret_302_moved_temporarily=2
	};

	ddwebpage( const ddstring& name, ddwebsite* site );
	virtual	~ddwebpage();

	ddwebcontext context;
	
	ddwebview& get_view( const ddstring& key="" );
	
	
	
	// alter müll
	virtual dd_result create_team_box( dditem& item );
	virtual dd_result create_member_box( dditem& item );
	
	// legacy kram
	virtual void       		add_inner_call( const ddstring& key, ddmemptr function, size_t access=3 );
  virtual void       		add_inner_call( const ddstring& key, const ddstring& itemkey=DDDEFAULTITEM, ddmemptr function=(ddmemptr) &ddwebpage::create_content, size_t access=3 );
	
	virtual dd_result 		create_content( dditem& item )
	{
		return rs_ok;
	}
	
	virtual dd_result  		create_redirect( const ddstring& redirect = "", dd_redirect_type redirecttype = ret_302_moved_temporarily );
	
	ddstring	fetch_draft_id( bool docreate=false );
	
  ddusermanager&     		get_user_manager();
  ddusersessionmanager& get_session_manager();
  ddwebgroupmgr&     		get_groups();
  
	ddstringrow&          get_split_path();
  const ddstring&    		get_raw_path();
  ddwebcgi&           	get_cgi();
  
 
	inline dddataconnection& get_data_connection()
	{
		return _dataconnection;
	}
	
	ddstring realdir;
	
	ddstring get_image_path( bool realdir=false );
	
	inline const ddstring& get_full_path()
	{
		return get_connection().get_request().get_full_path();
	}
	
	
  /**
  	@return the buffer of this pagelet.
  */

  inline ddiobuffer& get_buffer()
  {
		return _connection->get_buffer();
  }


  /**
  	Write a string into the output stream.
  */

  inline void write( const ddstring& text )
  {
  	get_buffer().append( text );
  }
  
  
  /**
  	@return the "body" item of the current page template.
    the body item is the main content area in the middle of the page.
    @see get_item()
  */

  inline dditem& get_body()
  {
  	return get_item()["sn_body"];
  }

	
	/**
		Die Connection für dieses Pagelet festlegen.
		@see ddwebconnection
	*/

	inline void set_connection( ddwebconnection* connection )
	{
		_connection = connection;
	}

	
	/**
  	Gibt eine Referenz auf die Connection dieses Pagelets zurück
  	@see ddwebconnection
  */

  inline ddwebconnection& get_connection()
  {
  	if( !_connection )
  		throw runtime_error( "ddwebpage::get_connection(): _connection==0" );
  	return *_connection;
  }
  
  
  /**
		Die UserID für dieses Pagelet festlegen.
		@see dduserid.
	*/
	
	void set_user_id( dduserid* userid )
	{
		if( 0 == userid )
			throw runtime_error( "ddwebpage::set_userid() user id==0" );
		_userid = userid;
	}
	
	
	/**
		Gibt eine Referenz auf die UserID dieses Pagelets zurück.
		@see dduserid.
	*/
	
	dduserid& get_user_id()
	{	
		if( !_userid )
			throw runtime_error( "ddwebpage::get_userid() userid==0" );
		return *_userid;
	}


  /**
  	Gibt die HTML-Vorlage für dieses Pagelet zurück.  	
  */

  inline dditem& get_item()
  {
  	if( !_item )
  		throw runtime_error( "get_item: item==0" );
  	return *_item;
  }


  /**
  	Gibt die Eltern-Site für dieses Pagelet zurück.
  */

  inline ddwebsite& get_site()
  {
  	if( !_site )
  		throw runtime_error( "get_site(): _site==0" );
  	return *_site;
  }

	
	/**
		Berechnet die url der letzten Seite eines mehrseitigen eintrags:
		z.B: /t/2223234/34
	*/
	
	virtual ddstring get_jump_last_url();
	
	
	/**
		Rendert das VG-Wort-Tag
	*/
	
	virtual ddstring get_vg_wort_tag()
	{
		return "";
	}
	
	/**
		Die Fehlermeldung, den Fehlercode setzen und 'rs_error' zurückgeben.
		Die Fehlerbehandlung passiert dann nicht hier sondern im @see ddwebpageproxy,
		der dazu die Routine des Servers benutzt.	
	*/
	
	inline dd_result create_error( const ddstring& errortext, int errorcode = ddwebresponse::ret_500_internal_server_error )
	{
		context.errortext = errortext;
		context.errorcode = errorcode;
		return rs_error;
	}
	
	
	// -------- proxy ------------------
	
	size_t        		enqueue_request( ddwebconnection* connection, dduserid* userid );
	void          		run();
	
	inline size_t get_request_count()
	{
		return _requestcount;
	}

	
	/**
		Alle Zähler zurücksetzen.
	*/
	
	inline void	reset_request_counter()
	{
		_requestcount = _queuemaxsize = _maxtimeout = _timeoutcount = 0;
	}
		
	
	/**
		Die aktuelle Größe der Wait-Queue.
	*/
	
	inline size_t get_queue_size()
	{
		return _queuesize;
	}


	/**
  	Die bisher maximale Größeder Wait-Queue.
  */
  
  inline size_t get_queue_max_size()
	{
		return _queuemaxsize;
	}
	
  
  /**
   Der bisher größte Timeout in Sekunden.
  */
  
  inline size_t get_max_timeout()
	{
		return _maxtimeout;
	}
	
	
	/**
		Die Anzahl der bisher aufgetretenen Timeouts.
	*/
	
  inline size_t get_timeout_count()
	{
		return _timeoutcount;
	}

	// -------- snpage ------------------
	
	//virtual dd_result create_pager_alert( dditem& item ); 
 	virtual dd_result create_count_selector( dditem& item );  
	virtual dd_result create_item_selector( dditem& item );  
	virtual dd_result create_type_selector( dditem& item );  
	virtual dd_result create_group_selector( dditem& item );  

	virtual dd_result create_user_content_count( dditem& item );				  
	//virtual dd_result create_pager_box( dditem& item );
	//virtual dd_result create_admin_pager_box( dditem& item );
 
  //virtual void 			create_navigator( dditem& item, const ddstring& linkval, int from, int rows, int count, bool hint=false );
  //virtual void 			create_navigator_slim( dditem& item, const ddstring& linkval, int from, int rows, int count, bool hint=false );
  
  virtual dd_result execute_call( const ddstring& key, dditem& item );

protected:
  
 	//void 			 						add_table( ddconfigsection& config, const ddstring& connectstring );
  dditem*    						lookup_item( const ddstring& rawkey );
	
	void 									add_request_handler( const ddstring& key, const ddstring& itemkey, ddmemptr function=(ddmemptr) &ddwebpage::create_content, size_t pathlen=1, size_t access=3 );
	
  ddwebconnection*			_connection;
 
  dduserid*         		_userid;  
  dditem*								_item;
  ddwebsite*        		_site; 
	
 	dddataconnection			_dataconnection;

	//dddbtablemap					_tables;
	dditemptrmap      		_items;
	ddwebpagecallmap			_functions;  
	
protected: // proxy

	bool  								dequeue_request( ddwebpagerequest& request );
	void 									webpage_handle_request( ddwebpagerequest& request );
	dd_result  						webpage_handle_content( ddwebconnection& connection, dduserid& user );	
	void									webpage_handle_error( ddwebconnection* connection, const ddstring& errortext, int errorcode );

  ddwebpagerequestqueue	_queue;
  size_t			 					_queuesize;
  size_t			 					_queuemaxsize;
  size_t			 					_requestcount;
	time_t			 					_maxtimeout;
	time_t			 					_timeoutcount;
	ddthreadmutex					_mutex;
  int					 					_fifo;
  
  //ddthreadmutex	 	_sesmgrlock;

};


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

    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.

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


class ddwebpageauto : public ddwebpage
{

public:

  ddwebpageauto( const ddstring& name, ddwebsite* site );

protected:

	void init_page( const ddstring& configstr );
	
};


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

    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.

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

class ddwebpagestatic : public ddwebpageauto
{

public:

  ddwebpagestatic( const ddstring& name, ddwebsite* site );
	
};

class ddwebpagehelp : public ddwebpageauto
{

public:

  ddwebpagehelp( const ddstring& name, ddwebsite* site );
	
};


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

    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.

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


/**
	moo.
*/

class sxpagehelp : public ddwebpageauto
{

public:

  sxpagehelp( const ddstring& name, ddwebsite* site );

};


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

    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.

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


/// ddwebpagemap: speichert die Pagelets.
/**
	ddwebpagemap: speichert die Pagelets.
*/

class ddwebpagemap : public ddmapptr<ddwebpage>
{

public:
	
  ddwebpage* lookup( const ddstring& matchkey ); 

};

#endif
