bool IRCClient::part ( std::string channel, std::string reason )
{
  // we need to have at LEAST sent the username and stuff
  if (getConnectionState() < eSentNickAndUSer)
    return false;

  IRCCommandInfo  info;
  info.target = channel;
  if ( reason.size())
	  info.params.push_back(reason);

  if (!sendIRCCommand(eCMD_PART,info))
  {
    log("part Failed: PART command not sent",0);
    return false;
  }

  // notify that we parted the channel
  std::string nick = getNick();
  userManager.userPartChannel(nick, channel);

  trClientPartEventInfo  eventInfo;

  eventInfo.eventType = eIRCChannelPartEvent;
  eventInfo.reason = reason;
  eventInfo.user = getNick();

  callEventHandler(eventInfo.eventType,eventInfo);

  // todo, we really should go and remove the channel from our listing and kill any dead users
  return true;
}
bool cPlayer::onTradeStart( P_PLAYER partner, P_ITEM firstitem )
{
	bool result = false;

	if (canHandleEvent(EVENT_TRADESTART)) {
		PyObject* args = Py_BuildValue( "(O&O&O&)", PyGetCharObject, this, PyGetCharObject, partner, PyGetItemObject, firstitem );
		result = callEventHandler( EVENT_TRADESTART, args );
		Py_DECREF( args );
	}

	return result;
}
bool cPlayer::onLogin( void )
{
	bool result = false;

	if ( canHandleEvent( EVENT_LOGIN ) )
	{
		PyObject* args = Py_BuildValue( "(O&)", PyGetCharObject, this );
		result = callEventHandler( EVENT_LOGIN, args );
		Py_DECREF( args );
	}

	return result;
}
bool cPlayer::onUse( P_ITEM pItem )
{
	bool result = false;

	if ( canHandleEvent(EVENT_USE) )
	{
		PyObject* args = Py_BuildValue( "O&O&", PyGetCharObject, this, PyGetItemObject, pItem );
		result = callEventHandler( EVENT_USE, args );
		Py_DECREF( args );
	}

	return result;
}
bool cPlayer::onCastSpell( unsigned int spell )
{
	bool result = false;

	if ( canHandleEvent( EVENT_CASTSPELL ) )
	{
		PyObject* args = Py_BuildValue( "O&i", PyGetCharObject, this, spell );
		result = callEventHandler( EVENT_CASTSPELL, args );
		Py_DECREF( args );
	}

	return result;
}
bool cPlayer::onTrade( unsigned int type, unsigned int buttonstate, SERIAL itemserial )
{
	bool result = false;

	if ( canHandleEvent(EVENT_TRADE) )
	{
		PyObject* args = Py_BuildValue( "(O&iii)", PyGetCharObject, this, type, buttonstate, itemserial );

		result = callEventHandler(EVENT_TRADE, args );

		Py_DECREF( args );
	}

	return result;
}
// Find our module name
bool cPythonScript::load( const QCString& name )
{
	if ( name.isEmpty() )
	{
		return false;
	}

	setName( name );

	codeModule = PyImport_ImportModule( const_cast<char*>( name.data() ) );

	if ( !codeModule )
	{
		reportPythonError( name );
		return false;
	}

	// Call the onLoad event
	callEventHandler( "onLoad", 0, true );

	if ( PyErr_Occurred() )
	{
		reportPythonError( name_ );
	}

	// Cache Event Functions
	for ( unsigned int i = 0; i < EVENT_COUNT; ++i )
	{
		if ( PyObject_HasAttrString( codeModule, eventNames[i] ) )
		{
			events[i] = PyObject_GetAttrString( codeModule, eventNames[i] );

			if ( events[i] && !PyCallable_Check( events[i] ) )
			{
				Console::instance()->log( LOG_ERROR, QString( "Script %1 has non callable event: %1" ).arg( eventNames[i] ) );

				Py_DECREF( events[i] );
				events[i] = 0;
			}
		}
	}

	loaded = true;
	return true;
}
/*
	\event onUnload
	\return None
	\condition Triggered when the script is unloaded.
*/
void cPythonScript::unload( void )
{
    loaded = false;

    // Free Cached Events
    for ( unsigned int i = 0; i < EVENT_COUNT; ++i )
    {
        if ( events[i] )
        {
            events[i] = 0;
        }
    }

    callEventHandler( "onUnload" );

    Py_XDECREF( codeModule );
    codeModule = 0;
}
// Find our module name
bool cPythonScript::load( const QByteArray& name )
{
    if ( name.isEmpty() )
    {
        return false;
    }

    setName( name );

    codeModule = PyImport_ImportModule( const_cast<char*>( name.data() ) );

    if ( !codeModule )
    {
        reportPythonError( name );
        return false;
    }

    // Call the onLoad event
    callEventHandler( "onLoad", 0, true );

    if ( PyErr_Occurred() )
    {
        reportPythonError( name_ );
    }

    // Get and cache the module's dictionary
    PyObject *pDict = PyModule_GetDict(codeModule); // BORROWED REFERENCE

    // Cache Event Functions
    for (unsigned int i = 0; i < EVENT_COUNT; ++i) {
        events[i] = PyDict_GetItemString( pDict, eventNames[i] );

        if (events[i] && !PyCallable_Check(events[i])) {
            Console::instance()->log( LOG_ERROR, tr( "Script %1 has non callable event: %1.\n" ).arg(QString(name_)).arg( eventNames[i] ) );
            Py_DECREF(events[i]);
            events[i] = 0;
        }
    }

    loaded = true;
    return true;
}