
/* AMX Mod script.
*
* (c) Copyright 2002, OLO
* This file is provided as is (no warranties).
*
*/

#include <amxmod>

#define B_BUF_LEN 64
#define S_BUF_LEN 32

#define MAX_MAPS 64
#define MAX_CMDS 64
#define MAX_PPL 24
#define MAX_CVARS 32

new bool:cstrike_running

new map_dat[MAX_MAPS][S_BUF_LEN+1]
new map_num = 0

new cmd_name_dat[MAX_CMDS][S_BUF_LEN+1]
new cmd_cmd_dat[MAX_CMDS][B_BUF_LEN+1]
new cmd_misc_dat[MAX_CMDS][2]
new cmd_num = 0

new ppl_name_dat[MAX_PPL][S_BUF_LEN+1]
new ppl_cmd_dat[MAX_PPL][B_BUF_LEN+1]
new ppl_misc_dat[MAX_PPL][2]
new ppl_num = 0

new cvar_name_dat[MAX_CVARS][S_BUF_LEN+1]
new cvar_misc_dat[MAX_CVARS][32]
new cvar_cmd_dat[MAX_CVARS*5][B_BUF_LEN+1]
new cvar_cmd_num = 0
new cvar_num = 0

new user_options[33][64]
new user_position[33]
new user_players[33][32]
new user_select[33]
new user_select_max[33]

/* action of selected option */
public action_main_menu(id,key){
	switch(key){
		case 0: {
			user_select_max[id] = ppl_options(get_user_flags(id),user_options[id])
			if (user_select[id] >= user_select_max[id]) user_select[id] = 0
			show_ppl_menu(id,0)
		}
		case 1: {
			cmd_options(get_user_flags(id),user_options[id])
			show_cmd_menu(id,0)
		}
		case 2: {
			show_cvar_menu(id,0)
		}
		case 3: {
			if (user_select[id] > 3) user_select[id] = 0
			show_map_menu(id,0)
		}
	}
	return PLUGIN_HANDLED
}

public action_cmd_menu(id,key){
	if (key==8){
		show_cmd_menu(id,++user_position[id])
	}
	else if (key==9){
		if (--user_position[id] < 0)
			show_main_menu(id)
		else
			show_cmd_menu(id,user_position[id])
	}
	else {
		new option = user_position[id] * 8 + key
		new ctype = cmd_misc_dat[user_options[id][option]][1]
		new command[B_BUF_LEN+1]
		copy(command,B_BUF_LEN,cmd_cmd_dat[user_options[id][option]])
		while(replace(command,B_BUF_LEN,"\'","^"")){}
		if (ctype & 1)
			server_cmd(command)
		else if (ctype & 2)
			client_cmd(id,command)
		else if (ctype & 4)
			client_cmd(0,command)
		if (ctype & 8)
			show_main_menu(id)
		else if (!(ctype & 16))	
			show_cmd_menu(id,user_position[id])		
	}
	return PLUGIN_HANDLED
}

public action_map_menu(id,key){
	if (key==7) {
		if (++user_select[id] > 3) user_select[id] = 0
		show_map_menu(id,user_position[id])
	}
	else if (key==8){
		show_map_menu(id,++user_position[id])
	}
	else if (key==9){
		if (--user_position[id] < 0)
			show_main_menu(id)
		else
			show_map_menu(id,user_position[id])
	}
	else {
		new option = user_position[id] * 7 + key
		switch(user_select[id]){
		case 0:	client_cmd(id,"amx_map %s",map_dat[option])
		case 1:	client_cmd(id,"amx_map %s 3",map_dat[option])
		case 2:	client_cmd(id,"amx_votemap %s",map_dat[option])
		case 3:	{
				set_cvar_string("amx_nextmap",map_dat[option])
				show_map_menu(id,user_position[id])
			}
		}
	}
	return PLUGIN_HANDLED
}

public action_cvar_menu(id,key){
	if (key==8){
		show_cvar_menu(id,++user_position[id])
	}
	else if (key==9){
		if (--user_position[id] < 0)
			show_main_menu(id)
		else
			show_cvar_menu(id,user_position[id])
	}
	else {
		new option = user_position[id] * 8 + key
		new omax = cvar_misc_dat[user_options[id][option]][1]
		new cvalue[65], a
		get_cvar_string(cvar_name_dat[user_options[id][option]],cvalue,63)
		for(a = 2; a < omax; ++a){
			if (equal(cvalue,cvar_cmd_dat[cvar_misc_dat[user_options[id][option]][a]]))	{
				if (a >= omax - 1)
					a = 2
				else
					a++
				set_cvar_string(cvar_name_dat[user_options[id][option]],cvar_cmd_dat[cvar_misc_dat[user_options[id][option]][a]])
				break;
			}
		}
		if (a >= omax) set_cvar_string(cvar_name_dat[user_options[id][option]],cvar_cmd_dat[cvar_misc_dat[user_options[id][option]][2]])
		show_cvar_menu(id,user_position[id])
	}
	return PLUGIN_HANDLED
}

public action_ppl_menu(id,key){
	if (key==7) {
		if (++user_select[id] >= user_select_max[id]) user_select[id] = 0
		show_ppl_menu(id,user_position[id])
	}
	else if (key==8){
		show_ppl_menu(id,++user_position[id])
	}
	else if (key==9){
		if (--user_position[id] < 0)
			show_main_menu(id)
		else
			show_ppl_menu(id,user_position[id])
	}
	else {
		new option = user_position[id] * 7 + key
		new index = user_players[id][option]
		new ctype = ppl_misc_dat[user_options[id][user_select[id]]][1]
		if (is_user_connected(index)) {
			new command[B_BUF_LEN+1], authid[17], name[S_BUF_LEN+1]
			copy(command,B_BUF_LEN,ppl_cmd_dat[user_options[id][user_select[id]]])
			get_user_authid(index,authid,16)
			get_user_name(index,name,S_BUF_LEN)
			replace(command,B_BUF_LEN,"%authid%",authid)
			replace(command,B_BUF_LEN,"%name%",name)
			while(replace(command,B_BUF_LEN,"\'","^"")){}
			if (ctype & 1){
				server_cmd(command)
				server_exec()
			}
			else if (ctype & 2)
				client_cmd(id,command)
			else if (ctype & 4)
				client_cmd(index,command)
		}
		if (ctype & 8)
			show_main_menu(id)
		else if (!(ctype & 16))	
			show_ppl_menu(id,user_position[id])
	}
	return PLUGIN_HANDLED
}

/* gather informations */
cmd_options(flags,options[64]) {
	new onum = 0
	for(new a = 0; a < cmd_num; ++a)
		if (cmd_misc_dat[a][0] & flags)
			options[onum++] = a
	return onum
}
ppl_options(flags,options[64]) {
	new onum = 0
	for(new a = 0; a < ppl_num; ++a)
		if (ppl_misc_dat[a][0] & flags)
			options[onum++] = a
	return onum
}
cvar_options(flags,options[64]) {
	new onum = 0
	for(new a = 0; a < cvar_num; ++a)
		if (cvar_misc_dat[a][0] & flags)
			options[onum++] = a
	return onum
}
/* displaying */
show_main_menu(id){
	new menu_body[192]
	
	if (cstrike_running)
		copy(menu_body,191,"\yAMX Admin Menu^n\w^n\%c1. Player Menu\w^n\%c2. Cmd Menu\w^n\%c3. Cvar Menu\w^n\%c4. Map Menu\w^n^n0. Exit")
	else
		copy(menu_body,191,"AMX Admin Menu^n^n%c. Player Menu^n%c. Cmd Menu^n%c. Cvar Menu^n%c. Map Menu^n^n0. Exit")
	
	new c_ppl_m, c_cmd_m, c_cvar_m, c_map_m, keys = (1<<9)
	c_ppl_m = c_cmd_m = c_cvar_m = c_map_m = (cstrike_running ? 'd' : '#' )
	if (ppl_options(get_user_flags(id),user_options[id])){
		keys |= (1<<0)
		c_ppl_m = cstrike_running ? 'w' : '1'
	}
	if (cmd_options(get_user_flags(id),user_options[id])){
		keys |= (1<<1)
		c_cmd_m = cstrike_running ? 'w' : '2'
	}
	if (cvar_options(get_user_flags(id),user_options[id])){
		keys |= (1<<2)
		c_cvar_m = cstrike_running ? 'w' : '3'
	}
	if (map_num){	
		keys |= (1<<3)
		c_map_m = cstrike_running ? 'w' : '4'
	}
	user_position[id] = 0
	format(menu_body,190,menu_body,c_ppl_m,c_cmd_m,c_cvar_m,c_map_m)
	show_menu(id,keys,menu_body)
	return PLUGIN_HANDLED
}

show_cvar_menu(id,position){
	new menu_body[512]
	if (cstrike_running)	
	 copy(menu_body,511,"\yAMX Cvar Menu\R%d/%d^n\w^n")
	else
	 format(menu_body,511,"%-20s%%d/%%d^n^n","AMX Cvar Menu")
	 
	format(menu_body,511,menu_body,position + 1,((cvar_num/8)+((cvar_num%8)?1:0)))
	new temp[B_BUF_LEN+1], cval[B_BUF_LEN+1], start = position * 8, end = start + 8
	if (end > cvar_num) end = cvar_num
	new pos = 0, keys = (1<<9)
	for(new a = start; a < end; ++a){
		get_cvar_string(cvar_name_dat[user_options[id][a]],cval,B_BUF_LEN)
		
		if (cstrike_running)		
			format(temp,B_BUF_LEN,"%d. %s\R%s^n\w",pos + 1,cvar_name_dat[user_options[id][a]],cval)
		else
			format(temp,B_BUF_LEN,"%d. %-20s %s^n",pos + 1,cvar_name_dat[user_options[id][a]],cval)
		
		add(menu_body,511,temp)
		keys |= (1<<pos)
		pos++
	}
	if (end != cvar_num){
		add(menu_body,511,"^n9. More...^n0. Back")
		keys |= (1<<8)
	}
	else {
		add(menu_body,511,"^n0. Back")
	}
	show_menu(id,keys,menu_body)
	return PLUGIN_HANDLED
}

show_map_menu(id,position){
	new menu_body[512] 
	
	if (cstrike_running)	
	 copy(menu_body,511,"\yAMX Map Menu\R%d/%d^n\w^n")
	else
	 format(menu_body,511,"%-20s%%d/%%d^n^n","AMX Map Menu")	
	
	format(menu_body,511,menu_body,position + 1,((map_num/7)+((map_num%7)?1:0)))
	new temp[B_BUF_LEN+1], start = position * 7, end = start + 7
	if (end > map_num) end = map_num
	new pos = 0, keys = (1<<9)|(1<<7)
	for(new a = start; a < end; ++a){
		format(temp,B_BUF_LEN,"%d. %s^n",pos + 1,map_dat[a])
		add(menu_body,511,temp)
		keys |= (1<<pos)
		pos++
	}
	switch(user_select[id]){
	case 0: add(menu_body,511,"^n8. Change level^n")
	case 1: add(menu_body,511,"^n8. End level^n")
	case 2: add(menu_body,511,"^n8. Vote map^n")
	case 3: add(menu_body,511,"^n8. Set nextmap^n")
	}
	if (end != map_num){
		add(menu_body,511,"^n9. More...^n0. Back")
		keys |= (1<<8)
	}
	else {
		add(menu_body,511,"^n0. Back")
	}
	show_menu(id,keys,menu_body)
	return PLUGIN_HANDLED
}

show_cmd_menu(id,position){

	new menu_body[512]
	if (cstrike_running)	
	 copy(menu_body,511,"\yAMX Cmd Menu\R%d/%d^n\w^n")
	else
	 format(menu_body,511,"%-20s%%d/%%d^n^n","AMX Cmd Menu")

	format(menu_body,511,menu_body,position + 1,((cmd_num/8)+((cmd_num%8)?1:0)))
	new temp[B_BUF_LEN+1], start = position * 8, end = start + 8
	if (end > cmd_num) end = cmd_num
	new pos = 0, keys = (1<<9)
	for(new a = start; a < end; ++a){
		format(temp,B_BUF_LEN,"%d. %s^n",pos + 1,cmd_name_dat[user_options[id][a]])
		add(menu_body,511,temp)
		keys |= (1<<pos)
		pos++
	}
	if (end != cmd_num){
		add(menu_body,511,"^n9. More...^n0. Back")
		keys |= (1<<8)
	}
	else {
		add(menu_body,511,"^n0. Back")
	}
	show_menu(id,keys,menu_body)
	return PLUGIN_HANDLED
}

show_ppl_menu(id,position){

	new menu_body[512]
	if (cstrike_running)	
	 copy(menu_body,511,"\yAMX Player Menu\R%d/%d^n\w^n")
	else
	 format(menu_body,511,"%-20s%%d/%%d^n^n","AMX Player Menu")

	new inum, start = position * 7
	get_players(user_players[id],inum)
	if (start >= inum) start = position = user_position[id] = 0
	format(menu_body,511,menu_body,position + 1,((inum/7)+((inum%7)?1:0)))
	new temp[B_BUF_LEN+1], name[S_BUF_LEN+1], end = start + 7
	if (end > inum) end = inum
	new pos = 0, keys = (1<<9)|(1<<7), status[6]
	for(new a = start; a < end; ++a){
		get_user_name(user_players[id][a],name,S_BUF_LEN)
		if (get_user_flags(user_players[id][a])&ADMIN_IMMUNITY)	{
			if (cstrike_running)
				format(status,5,"\d%d",pos + 1)
			else
				copy(status,3,"#")			
		}
		else {
			num_to_str(pos + 1,status,3)
			keys |= (1<<pos)
		}
		if (cstrike_running)
			format(temp,B_BUF_LEN,"%s. %s^n\w",status,name)
		else
			format(temp,B_BUF_LEN,"%s. %s^n",status,name)		
		add(menu_body,255,temp)
		pos++
	}
	format(temp,B_BUF_LEN,"^n8. %s^n",ppl_name_dat[user_options[id][user_select[id]]])
	add(menu_body,511,temp)
	if (end != inum){
		add(menu_body,511,"^n9. More...^n0. Back")
		keys |= (1<<8)
	}
	else {
		add(menu_body,511,"^n0. Back")
	}
	show_menu(id,keys,menu_body)
	return PLUGIN_HANDLED
}

/* command amx_menu */
public admin_menu(id){

	if (!(get_user_flags(id)&ADMIN_CVAR)){
		client_print(id,print_console,"[AMX] You have no access to that command")
		return PLUGIN_HANDLED
	}

	show_main_menu(id)

	return PLUGIN_HANDLED
}

/* configuration */
public set_cvar_menu(){
	if (read_argc()>3&&cvar_num<MAX_CVARS){
		new data[B_BUF_LEN+1], a, cmax = read_argc() - 1
		read_argv(1,data,S_BUF_LEN)
		copy(cvar_name_dat[cvar_num],S_BUF_LEN,data)
		for(a = 2; a < cmax;a++){
			read_argv(a,data,B_BUF_LEN)
			copy(cvar_cmd_dat[cvar_cmd_num],B_BUF_LEN,data)
			cvar_misc_dat[cvar_num][a] = cvar_cmd_num++
			cvar_misc_dat[cvar_num][1] = a + 1
		}
		read_argv(a,data,S_BUF_LEN)
		cvar_misc_dat[cvar_num++][0] = read_flags(data)
	}
	return PLUGIN_HANDLED
}
public set_player_menu(){
	if (read_argc()>3&&ppl_num<MAX_PPL){
		new data[B_BUF_LEN+1]
		read_argv(1,data,S_BUF_LEN)
		copy(ppl_name_dat[ppl_num],S_BUF_LEN,data)
		read_argv(2,data,B_BUF_LEN)
		copy(ppl_cmd_dat[ppl_num],B_BUF_LEN,data)
		read_argv(3,data,S_BUF_LEN)
		ppl_misc_dat[ppl_num][1] = read_flags(data)
		read_argv(4,data,S_BUF_LEN)
		ppl_misc_dat[ppl_num++][0] = read_flags(data)
	}
	return PLUGIN_HANDLED
}
public set_cmd_menu(){
	if (read_argc()>4&&cmd_num<MAX_CMDS){
		new data[B_BUF_LEN+1]
		read_argv(1,data,S_BUF_LEN)
		copy(cmd_name_dat[cmd_num],S_BUF_LEN,data)
		read_argv(2,data,B_BUF_LEN)
		copy(cmd_cmd_dat[cmd_num],B_BUF_LEN,data)
		read_argv(3,data,S_BUF_LEN)
		cmd_misc_dat[cmd_num][1] = read_flags(data)
		read_argv(4,data,S_BUF_LEN)
		cmd_misc_dat[cmd_num++][0] = read_flags(data)
	}
	return PLUGIN_HANDLED
}
public set_map_menu(){
	if (read_argc()>1&&map_num<MAX_MAPS){
		new data[S_BUF_LEN+1]
		read_argv(1,data,S_BUF_LEN)
		if (is_map_valid(data))
			copy(map_dat[map_num++],S_BUF_LEN,data)
	}
	return PLUGIN_HANDLED
}

/* initialization */
public plugin_init() {
	register_plugin("Admin Menu","0.6","default")
	register_menucmd(register_menuid("AMX Admin Menu"),1023,"action_main_menu")
	register_menucmd(register_menuid("AMX Cmd Menu"),1023,"action_cmd_menu")
	register_menucmd(register_menuid("AMX Map Menu"),1023,"action_map_menu")
	register_menucmd(register_menuid("AMX Player Menu"),1023,"action_ppl_menu")
	register_menucmd(register_menuid("AMX Cvar Menu"),1023,"action_cvar_menu")
	register_srvcmd("amx_pmenu","set_player_menu")
	register_srvcmd("amx_vmenu","set_cvar_menu")
	register_srvcmd("amx_cmenu","set_cmd_menu")
	register_srvcmd("amx_amenu","set_map_menu")
	register_clcmd("amx_menu","admin_menu",ADMIN_IMMUNITY,"amx_menu")
	server_cmd("exec addons/amx/menu.cfg")
	new mod_name[33]
	get_modname(mod_name,32)
	cstrike_running = equal(mod_name,"cstrike") ? true : false
	return PLUGIN_CONTINUE
}

