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

    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 DDUSERID_H
#define DDUSERID_H


#include <ddiourl.h>
#include <dddatatable.h>
#include <unistd.h>
#include <dddataobject.h>

class dduserid;
class ddusermanager;
class ddusermanager_alt;

/// dduserid: Speichert Userdaten und persönliche Einstellungen.
/**
		Nach den nervigen Dauercrashes hier eine komplette 
		Dau-Neuimplementierung um den Bug zu tracken
*/

//class dduserid : public dddataobject<ddusermanager>
class dduserid : public ddbaseobject
{

friend class ddusermanager;
			
		
public:
		
 	enum dd_user_right
	{
		usr_is_guest = 1,
   	usr_is_member = 2,
		usr_is_moderator = 4,
		usr_is_admin = 8,
		usr_is_root = 16,
		
		usr_is_registered = 30,		
		
		usr_can_edit_msg = 32,
		usr_can_edit_news = 64,		
		usr_can_edit_usr = 128,
		usr_can_edit_sale = 256,		
		usr_can_edit_comment = 512,
		usr_can_edit_vote = 1024,
		usr_can_edit_drivers = 2048,
		usr_can_edit_faq = 4096,
					
		usr_can_edit_chat = 8192
		
		//...
  };
	
	// FIX! Abhängig von der Feldreihenfolge der Datenbankabfrage!
	// select id id_user, sn_nickname, sn_cryptopass, sn_nickmail, sn_addressbook, sn_googlechannel1, sn_googlechannel2, sn_itemsperpage, sn_mailalert
	
	/*
	enum dd_user_field
	{
		usr_id=0,
		usr_nick_name,
		usr_passwd,
 		usr_nick_mail,
		usr_address_book,   		
 
		usr_google_channel1,
		usr_google_channel2,
		
		usr_items_per_page,
	 	usr_mail_alert,
	 	
	 	usr_field_size
		
	};
	*/
	
	/*
		
		+-------+---------------+-----------------+
		| id    | sn_nickname   | sn_accessrights |
		+-------+---------------+-----------------+
		|  6879 | Butzefrau     |           15342 |
		| 19748 | cyc           |           16382 |
		|     4 | halfstone     |           16382 |
		|   123 | Locke         |           15342 |
		|  7489 | Mickey        |           15342 |
		|   691 | MixMax        |           15342 |
		|  5833 | Rangoo        |           15342 |
		|    76 | Thomas        |           15342 |
		|    48 | Unforgiven_II |           15342 |
		+-------+---------------+-----------------+

	*/
	
	//dduserid();
	// das ist ein guest
	dduserid( ddusermanager* parent );
	// das ist ein member
	dduserid( ddusermanager* parent, dddatastaterow& row );
	
	virtual ~dduserid();
	
	inline bool check_access( int flag ) const 
	{
		return ( _useraccessrights & flag );
	}
	
	inline bool is_guest() const 
	{
		// OOPS! sind alle members auch guests?
		// NEIN!
		return ( _useraccessrights & usr_is_guest );
	}
	
	inline bool is_member() const 
	{
		return ( _useraccessrights & usr_is_member );
	}
	
	
	/**
		Das ist Pfusch, liegt aber daran, das alle SubAdmin-Rechte
		auf 'can_edit_new' gebucht wurden.
	*/
	
	inline bool is_sub_admin() const 
	{
		return is_admin() || ( _useraccessrights & usr_can_edit_news );
	}
	
	inline bool is_admin() const 
	{
		return ( _useraccessrights & usr_is_admin );
	}
	
  inline bool is_root() const 
	{
		return ( _useraccessrights & usr_is_root );
	}
	
	inline bool is_registered() const 
	{
		return ( _useraccessrights & usr_is_registered );
	}
	
 	void 				 		sync( ddwebcgi& cgi );

	ddstring 			  to_string() const;
	
	inline ddusermanager& get_user_manager()
	{
		return *_parent;
	}
	
	
	
	
	/**
		@return Die Anzahl Zeilen pro Seite
	*/

	inline int get_items_per_page()
	{	
		// darf eigentlich nicht vorkommen...
		if( _useritemperpage < 10 )
			_useritemperpage = 30;
		return _useritemperpage;
	}
		
	inline const ddstring& get_session_key() const
  {
  	return _sessionkey;
  }
	
	/**
		@return Den ersten googlechannel des users
	*/

	inline const ddstring& get_google_channel1() const
	{	
		//return (*this)[dduserid::usr_google_channel1];
		return _usr_google_channel1;
	}
	
	
	/**
		@return Den zweiten googlechannel des users
	*/

	inline const ddstring& get_google_channel2() const
	{	
		return _usr_google_channel2;
	}
	
	
	/**
		@return Die Bonuspunkte für die Beantwortung einer Frage dieses Members.
	*/

	inline int get_rank_score() const
	{
		return 50;
	}
	
	
	/**
		Setzt die Anzahl Zeilen pro Seite
		Set the items per page for a user.
		@param the new item count.
		@return true when the value was valid. ( 0 < value < 50 )
	*/
	
	inline bool set_items_per_page( const ddstring& itemsperpage )
	{
		return set_items_per_page_int( itemsperpage.as_int() );
	}
	
	bool set_items_per_page_int( int itemsperpage )
	{
		_useritemperpage = itemsperpage;
		if( !_useritemperpage || _useritemperpage > DDMAXITEMSPERPAGE )
		{
			_useritemperpage = DDDEFAULTITEMSPERPAGE;
			return false;
		}
		return true;
	}
	
	/**
  	@return Die user-id (==database key).
  */

  inline const ddstring& get_id() const
  {
  	//return (*this)[dduserid::usr_id];
  	return  _usr_id;
  }

	  
	/**
  	@return Den Nickname.
  */

  inline const ddstring& get_nick_name() const
  {
  	//return (*this)[dduserid::usr_nick_name];
  	return  _usr_nick_name;
  }

	
	/**
  	Einen neuen nickname setzen. guest users only.
  */
	
	void set_nick_name( const ddstring& newnick );

	
	/**
  	Eine neue nickmail setzen. guest users only.
  */
	
	void set_nick_mail( const ddstring& newnick );
	
	
  /**
  	@return das (verschlüsselte) passwort.
  */

  inline const ddstring& get_passwd() const
  {
  	return  _usr_passwd;
  }
  
  
  /**
  	Ein neues crypto-passwd setzen
  */
	
	void set_passwd( const ddstring& newpass )
	{
		_usr_passwd = newpass;
	}
	
	
	/**
  	@return die aktuelle mail-adresse.
  */

  inline const ddstring& get_nick_mail() const
  {
  	return  _usr_nick_mail;
  }


	/**
  	@return das pager-adressbuch.
  */

  inline const ddstring& get_address_book() const
  {
  	return  _usr_address_book;
  }
   
  inline void set_address_book( const ddstring& usr_address_book )
  {
  	_usr_address_book = usr_address_book;
  }

 
  inline const ddstringmap& get_property_map() const
  {
  	return _properties;
  }
  
  inline const ddstring& get_property( const ddstring& key )
  {
  	if( _properties[key].empty() )
  		init_properties();
  	return _properties[key];
  }
  
  
  inline const bool check_property( const ddstring& key )
  {
  	if( _properties[key].empty() )
  		init_properties();
  		
  	const ddstring& prop = _properties[key];  	
  	return ( prop == "1" || prop == "true" );
  	
  }
  
  
  inline void set_property( const ddstring& key, const ddstring& value )
  {
  	_properties[key] = value;
  }
 
 	inline void clear_property( const ddstring& key )
  {
  	_properties.erase( key );
  }
  
  /**
  	@return the accerights of this user.
  */

  size_t get_access_rights() const
  {
  	return _useraccessrights;
  }

	void set_access_rights( size_t accessrights )
  {
  	_useraccessrights = accessrights;
  }
  
	/**
  	@return the last access time of this user id.
  */

  inline time_t get_access_time() const
  {
  	return _lastaccess;
  }


  /**
  	Set accesstime to "now"
   	@param now a time_t value.
  */

	inline void update_access_time()
	{
		_lastaccess = ::time(0);
	}


	/**
  	@return the last access time of this user id.
  */

  inline time_t get_last_posting_time() const
  {
  	return _lastpost;
  }


  /**
  	Set accesstime to "now"
   	@param now a time_t value.
  */

  inline void update_posting_time()
  {
  	_lastpost = ::time( 0 );
  }
	
	
	/**
		Gibt den Zeitpunkt des letzten Admin-Alerts
		zurück (Es soll nur alle x Sekunden ein alert
		geschickt werden können, um Spam zu vermeiden.
	*/
	
 	inline time_t get_last_alert_time() const
	{
  	return _lastalert;
  }

	
	/**
		Letzten Admin-Alert Zeitpunkt merken.
	*/
	
	inline void update_alert_time()
  {
  	_lastalert = ::time( 0 );
  }
		
		
	/**
		@return the hitcount for this userid.
	*/
	
	inline int get_hits() const
	{
		return _hits;
	}
	
  inline void increment_hits()
	{
		_hits++;
	}
	
	bool get_accepting_terms_flag() const;

	inline void set_accepting_terms_flag( bool flag )
	{		
		_acceptterms = flag;
	}
	
	/**
		Gibt das Mail-Alert-Flag zurück@return  Ist bei members default false,
		bei guests true.
	*/
	
	inline bool get_mail_alert_flag() const
	{
		return _mailalert;
	}
	

	/**
		@return Setzt das Mail-Alert-Flag
	*/
	
	bool set_mail_alert_flag( bool mailalert );

	
	/**
		@return Die ip-addresse des users.
	*/
	
	inline const ddstring& get_host_ip() const
	{
		return _hostip;
	}
	
	inline void set_host_ip( const ddstring& hostip )
	{
		_hostip = hostip;
	}
	
	inline bool user_is_locked()
	{
		return (_lockcount>0);
	}
	
	inline void user_lock()
	{
		_lockcount++;
	}
	
	inline void user_unlock()
	{
		_lockcount--;
	}
	
	
	inline const ddstring& get_last_login_date() const
	{
		return _lastlogindate;
	}
	
	inline void set_last_login_date( const ddstring& lastlogindate )
	{
		_lastlogindate = lastlogindate;
	}
	
	
	inline void set_system_message( const ddstring& sysmessage1, const ddstring& sysmessage2="", const ddstring& syslink = "" )
	{
		set_property( "sn_sysmessage1", sysmessage1 );
		set_property( "sn_sysmessage2", sysmessage2 );
		set_property( "sn_sysmessage3", syslink );
	}
	
	inline void clear_system_message()
	{
		set_system_message( "", "", "" );
	}
	
	
	inline const ddstring& get_prepared_nickname() const
	{
		return _preparednickname;
	}
	
	inline void set_prepared_nickname( const ddstring& preparednickname )
	{
		_preparednickname = preparednickname;
	}
	
	void init_properties();
	void save_properties();
	void reset_properties();
	
protected:

	// neu
	ddusermanager*	_parent;
	
	// alt
 	size_t			_useraccessrights;
	int         _useritemperpage;	
	time_t			_lastaccess;
	time_t			_lastpost;
	time_t			_lastalert;
	int 				_hits;		
	bool 				_acceptterms;
	bool				_mailalert;
	int 				_lockcount;
	ddstring		_hostip;
 	


	
	// neu
	ddstring				_usr_id;
	ddstring				_usr_nick_name;
	ddstring				_usr_passwd;
 	ddstring				_usr_nick_mail;
	ddstring				_usr_address_book;   		
 
	ddstring				_usr_google_channel1;
	ddstring				_usr_google_channel2;
	
	ddstring		_lastlogindate; 
	
	ddstring		_sysmessage; 
	ddstring		_preparednickname; 
	ddstring		_sessionkey;
	
	ddstring		_propertiesstring;
	
	ddstringmap	_properties;
	
};


typedef set<dduserid*> dduseridset;
// warum so kompliziert?
// fehlversuchtypedef ddmapptr<dduserid> dduseridptrmap;
//typedef map<ddstring,dduserid*> dduseridmap;
typedef ddmapptr<dduserid> dduseridmap;




#endif


