//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_networkmonitor_startup()
{
	//This code stolen from the bb4win SDK example

	//Initialize the usages to 0.0 to start
	for (int i = 0; i < AGENTTYPE_NETWORKMONITOR_NUMINTERFACES; i++)
	{
		for(int j = 0; j < AGENTTYPE_NETWORKMONITOR_NUMTYPES; j++)
		{
			agenttype_networkmonitor_previous_values[i][j] = -1.0;
			agenttype_networkmonitor_values[i][j] = 0.0;
			StrFormatByteSizeOrg(0,agenttype_networkmonitor_textvalues[i][j]);
		}
	}

	//Create the list
	agenttype_networkmonitor_agents = list_create();

	//Register the window class
	agenttype_networkmonitor_windowclassregistered = false;
	if (window_helper_register(agenttype_networkmonitor_timerclass, &agenttype_networkmonitor_event))
	{
		//Couldn't register the window
		BBMessageBox(NULL, "failed on register class", "test", MB_OK);
		return 1;
	}
	agenttype_networkmonitor_windowclassregistered = true;

	//Create the window
	agenttype_networkmonitor_window = window_helper_create(agenttype_networkmonitor_timerclass);
	if (!agenttype_networkmonitor_window)
	{
		//Couldn't create the window
		BBMessageBox(NULL, "failed on window", "test", MB_OK);
		return 1;
	}


		//If we got this far, we can successfully use this function
		//Register this type with the AgentMaster
	agent_registertype(
		"Network Monitor",                   //Friendly name of agent type
		"NetworkMonitor",                    //Name of agent type
		CONTROL_FORMAT_DOUBLE|CONTROL_FORMAT_TEXT,				//Control type
		false,
		&agenttype_networkmonitor_create,
		&agenttype_networkmonitor_destroy,
		&agenttype_networkmonitor_message,
		&agenttype_networkmonitor_notify,
		&agenttype_networkmonitor_getdata,
		&agenttype_networkmonitor_menu_set,
		&agenttype_networkmonitor_menu_context,
		&agenttype_networkmonitor_notifytype
		);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_bitmap_startup()
{
	//Register this type with the ControlMaster
	agent_registertype(
		L"Bitmap",                           //Friendly name of agent type
		L"Bitmap",                           //Name of agent type
		CONTROL_FORMAT_IMAGE,               //Control type
		true,
		&agenttype_bitmap_create,           
		&agenttype_bitmap_destroy,
		&agenttype_bitmap_message,
		&agenttype_bitmap_notify,
		&agenttype_bitmap_getdata,
		&agenttype_bitmap_menu_set,
		&agenttype_bitmap_menu_context,
		&agenttype_bitmap_notifytype
		);

	//Register this type with the ControlMaster
	agent_registertype(
		L"Icon",                             //Friendly name of agent type
		L"Icon",                             //Name of agent type
		CONTROL_FORMAT_IMAGE,               //Control type
		true,
		&agenttype_icon_create,         
		&agenttype_bitmap_destroy,
		&agenttype_bitmap_message,
		&agenttype_bitmap_notify,
		&agenttype_bitmap_getdata,
		&agenttype_icon_menu_set,
		&agenttype_bitmap_menu_context,
		&agenttype_bitmap_notifytype
		);

	// Initialize GDI+
	if(Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) != 0)
	{
		BBMessageBox(0, L"Error starting GdiPlus.dll", szAppName, MB_OK | MB_ICONERROR | MB_TOPMOST);
		return 1;
	}

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//agenttype_mixer_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_mixer_startup_xp ()
{
	//No reciever window yet
	mixer_recieverregistered = false;

	//Register this type with the ControlMaster
	agent_registertype(
		"Mixer",                            //Friendly name of agent type
		"MixerScale",                       //Name of agent type
		CONTROL_FORMAT_SCALE|CONTROL_FORMAT_TEXT,               //Control format
		true,
		&agenttype_mixer_create_xp,
		&agenttype_mixer_destroy_xp,
		&agenttype_mixer_message_xp,
		&agenttype_mixer_notify_xp,
		&agenttype_mixer_getdata_xp,
		&agenttype_mixerscale_menu_set_xp,
		&agenttype_mixer_menu_context_xp,
		&agenttype_mixer_notifytype_xp
		);

	//Register this type with the ControlMaster
	agent_registertype(
		"Mixer",                            //Friendly name of agent type
		"MixerBool",                        //Name of agent type
		CONTROL_FORMAT_BOOL,                //Control format
		true,
		&agenttype_mixer_create_xp,
		&agenttype_mixer_destroy_xp,
		&agenttype_mixer_message_xp,
		&agenttype_mixer_notify_xp,
		&agenttype_mixer_getdata_xp,
		&agenttype_mixerbool_menu_set_xp,
		&agenttype_mixer_menu_context_xp,
		&agenttype_mixer_notifytype_xp
		);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_systeminfo_startup()
{
	//Create the list
	agenttype_systeminfo_agents = list_create();

	//Register the window class
	agenttype_systeminfo_windowclassregistered = false;
	if (window_helper_register(agenttype_systeminfo_timerclass, &agenttype_systeminfo_event))
	{
		//Couldn't register the window
		BBMessageBox(NULL, L"failed on register class", L"test", MB_OK);
		return 1;
	}
	agenttype_systeminfo_windowclassregistered = true;

	//Create the window
	agenttype_systeminfo_window = window_helper_create(agenttype_systeminfo_timerclass);
	if (!agenttype_systeminfo_window)
	{
		//Couldn't create the window
		BBMessageBox(NULL, L"failed on window", "test", MB_OK);
		return 1;
	}
	
	//initialize
	for (int i = 1; i < SYSTEMINFO_NUMTYPES; i++){
		agenttype_systeminfo_updatevalue(i);
	}

	//If we got this far, we can successfully use this function
	//Register this type with the AgentMaster
	agent_registertype(
		L"System Information",                   //Friendly name of agent type
		L"SystemInfo",                    //Name of agent type
		CONTROL_FORMAT_TEXT,				//Control type
		false,
		&agenttype_systeminfo_create,
		&agenttype_systeminfo_destroy,
		&agenttype_systeminfo_message,
		&agenttype_systeminfo_notify,
		&agenttype_systeminfo_getdata,
		&agenttype_systeminfo_menu_set,
		&agenttype_systeminfo_menu_context,
		&agenttype_systeminfo_notifytype
		);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_diskspacemonitor_startup()
{
	//Create the list
	agenttype_diskspacemonitor_agents = list_create();

	//Register the window class
	agenttype_diskspacemonitor_windowclassregistered = false;
	if (window_helper_register(agenttype_diskspacemonitor_timerclass, &agenttype_diskspacemonitor_event))
	{
		//Couldn't register the window
		BBMessageBox(NULL, "failed on register class", "test", MB_OK);
		return 1;
	}
	agenttype_diskspacemonitor_windowclassregistered = true;

	//Create the window
	agenttype_diskspacemonitor_window = window_helper_create(agenttype_diskspacemonitor_timerclass);
	if (!agenttype_diskspacemonitor_window)
	{
		//Couldn't create the window
		BBMessageBox(NULL, "failed on window", "test", MB_OK);
		return 1;
	}

	//If we got this far, we can successfully use this function
	//Register this type with the AgentMaster
	agent_registertype(
		"DiskSpace Monitor",                   //Friendly name of agent type
		"DiskSpaceMonitor",                    //Name of agent type
		CONTROL_FORMAT_SCALE|CONTROL_FORMAT_TEXT,				//Control type
		false,
		&agenttype_diskspacemonitor_create,
		&agenttype_diskspacemonitor_destroy,
		&agenttype_diskspacemonitor_message,
		&agenttype_diskspacemonitor_notify,
		&agenttype_diskspacemonitor_getdata,
		&agenttype_diskspacemonitor_menu_set,
		&agenttype_diskspacemonitor_menu_context,
		&agenttype_diskspacemonitor_notifytype
		);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_switchedstate_startup()
{
	//Register this type with the ControlMaster
	agent_registertype(
		"Switched State Value",              //Friendly name of agent type
		"SwitchedState",                    //Name of agent type
		CONTROL_FORMAT_TEXT|CONTROL_FORMAT_TRIGGER|CONTROL_FORMAT_IMAGE,   //Control type
		false,
		&agenttype_switchedstate_create,            
		&agenttype_switchedstate_destroy,
		&agenttype_switchedstate_message,
		&agenttype_switchedstate_notify,
		&agenttype_switchedstate_getdata,
		&agenttype_switchedstate_menu_set,
		&agenttype_switchedstate_menu_context,
		&agenttype_switchedstate_notifytype
		);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_system_startup()
{
	//Register this type with the ControlMaster
	agent_registertype(
		"System/Shell",                 //Friendly name of agent type
		"System",                           //Name of agent type
		CONTROL_FORMAT_TRIGGER,             //Control type
		true,
		&agenttype_system_create,
		&agenttype_system_destroy,
		&agenttype_system_message,
		&agenttype_system_notify,
		&agenttype_system_getdata,
		&agenttype_system_menu_set,
		&agenttype_system_menu_context,
		&agenttype_system_notifytype
	);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_compoundtext_startup()
{
	//Register this type with the ControlMaster
	agent_registertype(
		"Compound Text",                      //Friendly name of agent type
		"CompoundText",                       //Name of agent type
		CONTROL_FORMAT_TEXT,                //Control format
		true,
		&agenttype_compoundtext_create,           
		&agenttype_compoundtext_destroy,
		&agenttype_compoundtext_message,
		&agenttype_compoundtext_notify,
		&agenttype_compoundtext_getdata,
		&agenttype_compoundtext_menu_set,
		&agenttype_compoundtext_menu_context,
		&agenttype_compoundtext_notifytype
		);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_graph_startup()
{
	//Create the list
	agenttype_graph_agents = list_create();

	//Register this type with the ControlMaster
	agent_registertype(
		"Graph",                          //Friendly name of agent type
		"Graph",                          //Name of agent type
		CONTROL_FORMAT_IMAGE,               //Control type
		true,
		&agenttype_graph_create,
		&agenttype_graph_destroy,
		&agenttype_graph_message,
		&agenttype_graph_notify,
		&agenttype_graph_getdata,
		&agenttype_graph_menu_set,
		&agenttype_graph_menu_context,
		&agenttype_graph_notifytype
	);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//controltype_button_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_systemmonitor_startup()
{
	//This code stolen from the bb4win SDK example


	OSVERSIONINFO osvinfo;
	ZeroMemory(&osvinfo, sizeof(osvinfo));
	osvinfo.dwOSVersionInfoSize = sizeof (osvinfo);
	GetVersionEx(&osvinfo);
	isnt2kxp =	osvinfo.dwPlatformId == VER_PLATFORM_WIN32_NT;

	//Initialize the usages to 0.0 to start
	for (int i = 0; i < SYSTEMMONITOR_NUMTYPES; i++)
	{
		agenttype_systemmonitor_previous_values[i] = -1.0;
		agenttype_systemmonitor_values[i] = 0.0;
		strcpy(agenttype_systemmonitor_textvalues[i], "0%");
	}

	//Create the list
	agenttype_systemmonitor_agents = list_create();

	//Register the window class
	agenttype_systemmonitor_windowclassregistered = false;
	if (window_helper_register(agenttype_systemmonitor_timerclass, &agenttype_systemmonitor_event))
	{
		//Couldn't register the window
		BBMessageBox(NULL, "failed on register class", "test", MB_OK);
		return 1;
	}
	agenttype_systemmonitor_windowclassregistered = true;

	//Create the window
	agenttype_systemmonitor_window = window_helper_create(agenttype_systemmonitor_timerclass);
	if (!agenttype_systemmonitor_window)
	{
		//Couldn't create the window
		BBMessageBox(NULL, "failed on window", "test", MB_OK);
		return 1;
	}

	//Load the library
	if(isnt2kxp)
	{
		agenttype_systemmonitor_ntdllmodule = NULL;
		agenttype_systemmonitor_ntdllmodule = LoadLibrary("ntdll.dll");

		//Check to make sure it loaded properly
		if (agenttype_systemmonitor_ntdllmodule == NULL)
		{
			//We couldn't load the NTDLL library
			//Return immediately
			return 1;
			BBMessageBox(NULL, "failed on ntdll", "test", MB_OK);
		}

		//Get the NtQuerySystemInformation function
		agenttype_systemmonitor_ntquerysysteminformation = NULL;
		agenttype_systemmonitor_ntquerysysteminformation = (agenttype_systemmonitor_NtQuerySystemInformation) GetProcAddress(agenttype_systemmonitor_ntdllmodule, "NtQuerySystemInformation");

		//Check to make sure we could get the function
		if (agenttype_systemmonitor_ntquerysysteminformation == NULL)
		{
			//Error - couldn't get the function call
			FreeLibrary(agenttype_systemmonitor_ntdllmodule);
			BBMessageBox(NULL, "failed on get proc address", "test", MB_OK);
			return 1;
		}


		// @NOTE: this uses undocumented nt api.  GetSystemInfo is the way to go
		//Get the number of processors
		/*BOOL status;
		SYSTEM_BASIC_INFORMATION basicinformation;
		status = agenttype_systemmonitor_ntquerysysteminformation(agenttype_systemmonitor_SystemBasicInformation, &basicinformation, sizeof(basicinformation), NULL);
		if (status != NO_ERROR)
		{
			//Couldn't get the number of processors
			FreeLibrary(agenttype_systemmonitor_ntdllmodule);
			BBMessageBox(NULL, "failed on processor", "test", MB_OK);
			return 1;
		}*/

		SYSTEM_INFO sysinfo;
		GetSystemInfo( &sysinfo );

		//Record the number of processors
		agenttype_systemmonitor_number_processors = sysinfo.dwNumberOfProcessors;

		//If it is less than 1 or more than 64... assume an error (I don't think any super clusters are running BBI)
		if (agenttype_systemmonitor_number_processors < 1 || agenttype_systemmonitor_number_processors > 64)
		{
			FreeLibrary(agenttype_systemmonitor_ntdllmodule);
			BBMessageBox(NULL, "failed on number of processors", "test", MB_OK);
			return 1;
		}
	}

		//If we got this far, we can successfully use this function
		//Register this type with the AgentMaster
	agent_registertype(
		"System Monitor",                   //Friendly name of agent type
		"SystemMonitor",                    //Name of agent type
		CONTROL_FORMAT_SCALE|CONTROL_FORMAT_TEXT,				//Control type
		false,
		&agenttype_systemmonitor_create,
		&agenttype_systemmonitor_destroy,
		&agenttype_systemmonitor_message,
		&agenttype_systemmonitor_notify,
		&agenttype_systemmonitor_getdata,
		&agenttype_systemmonitor_menu_set,
		&agenttype_systemmonitor_menu_context,
		&agenttype_systemmonitor_notifytype
		);

	//No errors
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//agenttype_winamp_startup
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int agenttype_winamp_startup()
{
	//Register the window class
	agenttype_winamp_windowclassregistered = false;
	if (window_helper_register(agenttype_winamp_timerclass, &agenttype_winamp_event))
	{
		//Couldn't register the window
		return 1;
	}
	agenttype_winamp_windowclassregistered = true;

	//Create the window
	agenttype_winamp_window = window_helper_create(agenttype_winamp_timerclass);
	if (!agenttype_winamp_window)
	{
		//Couldn't create the window
		return 1;
	}

	//Create the list
	agenttype_winamp_agents = list_create();

	//Register this type with the ControlMaster
	agent_registertype(
		"Winamp",                           //Friendly name of agent type
		"Winamp",                           //Name of agent type
		CONTROL_FORMAT_TRIGGER,             //Control format
		true,
		&agenttype_winamp_create,
		&agenttype_winamp_destroy,
		&agenttype_winamp_message,
		&agenttype_winamp_notify,
		&agenttype_winamp_getdata,
		&agenttype_winamp_menu_set,
		&agenttype_winamp_menu_context,
		&agenttype_winamp_notifytype
	);

	//Register this type with the ControlMaster
	agent_registertype(
		"Winamp",                           //Friendly name of agent type
		"WinampScale",                      //Name of agent type
		CONTROL_FORMAT_SCALE,               //Control format
		true,
		&agenttype_winamppoller_create,
		&agenttype_winamp_destroy,
		&agenttype_winamp_message,
		&agenttype_winamppoller_notify,
		&agenttype_winamppoller_getdata,
		&agenttype_winamppoller_scale_menu_set,
		&agenttype_winamp_menu_context,
		&agenttype_winamp_notifytype
	);

	//Register this type with the ControlMaster
	agent_registertype(
		"Winamp",                           //Friendly name of agent type
		"WinampBool",                       //Name of agent type
		CONTROL_FORMAT_BOOL,                //Control format
		false,
		&agenttype_winamppoller_create,
		&agenttype_winamp_destroy,
		&agenttype_winamp_message,
		&agenttype_winamppoller_notify,
		&agenttype_winamppoller_getdata,
		&agenttype_winamppoller_bool_menu_set,
		&agenttype_winamp_menu_context,
		&agenttype_winamp_notifytype
	);

	//Register this type with the ControlMaster
	agent_registertype(
		"Winamp",                           //Friendly name of agent type
		"WinampText",                       //Name of agent type
		CONTROL_FORMAT_TEXT,                //Control format
		true,
		&agenttype_winamppoller_create,
		&agenttype_winamp_destroy,
		&agenttype_winamp_message,
		&agenttype_winamppoller_notify,
		&agenttype_winamppoller_getdata,
		&agenttype_winamppoller_text_menu_set,
		&agenttype_winamp_menu_context,
		&agenttype_winamp_notifytype
	);

	//No errors
	return 0;
}