code:
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31

var/const/CALL_SHUTTLE_REASON_LENGTH = 12

// The communications computer
/obj/machinery/computer/communications
	name = "communications console"
	desc = "This can be used for various important functions. Still under developement."
	icon_state = "comm"
	req_access = list(access_heads)
	circuit = /obj/item/weapon/circuitboard/communications
	var/authenticated = 0
	var/auth_id = "Unknown" //Who is currently logged in?
	var/list/messagetitle = list()
	var/list/messagetext = list()
	var/currmsg = 0
	var/aicurrmsg = 0
	var/state = STATE_DEFAULT
	var/aistate = STATE_DEFAULT
	var/message_cooldown = 0
	var/ai_message_cooldown = 0
	var/tmp_alertlevel = 0
	var/const/STATE_DEFAULT = 1
	var/const/STATE_CALLSHUTTLE = 2
	var/const/STATE_CANCELSHUTTLE = 3
	var/const/STATE_MESSAGELIST = 4
	var/const/STATE_VIEWMESSAGE = 5
	var/const/STATE_DELMESSAGE = 6
	var/const/STATE_STATUSDISPLAY = 7
	var/const/STATE_ALERT_LEVEL = 8
	var/const/STATE_CONFIRM_LEVEL = 9
	var/const/STATE_TOGGLE_EMERGENCY = 10

	var/status_display_freq = "1435"
	var/stat_msg1
	var/stat_msg2

/obj/machinery/computer/communications/New()
	shuttle_caller_list += src
	..()

/obj/machinery/computer/communications/process()
	if(..())
		if(state != STATE_STATUSDISPLAY)
			src.updateDialog()

/obj/machinery/computer/communications/Topic(href, href_list)
	if(..())
		return
	if (src.z > ZLEVEL_STATION)
		usr << "Unable to establish a connection: \black You're too far away from the station!"
		return
	usr.set_machine(src)

	if(!href_list["operation"])
		return
	var/obj/item/weapon/circuitboard/communications/CM = circuit
	switch(href_list["operation"])
		// main interface
		if("main")
			src.state = STATE_DEFAULT
		if("login")
			var/mob/M = usr
			var/obj/item/weapon/card/id/I = M.get_active_hand()
			if (istype(I, /obj/item/device/pda))
				var/obj/item/device/pda/pda = I
				I = pda.id
			if (I && istype(I))
				if(src.check_access(I))
					authenticated = 1
					auth_id = "[I.registered_name] ([I.assignment])"
					if((20 in I.access))
						authenticated = 2
				if(src.emagged)
					authenticated = 2
					auth_id = "Unknown"
		if("logout")
			authenticated = 0

		if("swipeidseclevel")
			var/mob/M = usr
			var/obj/item/weapon/card/id/I = M.get_active_hand()
			if (istype(I, /obj/item/device/pda))
				var/obj/item/device/pda/pda = I
				I = pda.id
			if (I && istype(I))
				if(access_captain in I.access)
					var/old_level = security_level
					if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN
					if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN
					if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
					set_security_level(tmp_alertlevel)
					if(security_level != old_level)
						//Only notify the admins if an actual change happened
						log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
						message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
						switch(security_level)
							if(SEC_LEVEL_GREEN)
								feedback_inc("alert_comms_green",1)
							if(SEC_LEVEL_BLUE)
								feedback_inc("alert_comms_blue",1)
					tmp_alertlevel = 0
				else:
					usr << "You are not authorized to do this."
					tmp_alertlevel = 0
				state = STATE_DEFAULT
			else
				usr << "You need to swipe your ID."

		if("announce")
			if(src.authenticated==2 && !message_cooldown)
				make_announcement(usr)
			else if (src.authenticated==2 && message_cooldown)
				usr << "Intercomms recharging. Please stand by."

		if("callshuttle")
			src.state = STATE_DEFAULT
			if(src.authenticated)
				src.state = STATE_CALLSHUTTLE
		if("callshuttle2")
			if(src.authenticated)
				SSshuttle.requestEvac(usr, href_list["call"])
				if(SSshuttle.emergency.timer)
					post_status("shuttle")
			src.state = STATE_DEFAULT
		if("cancelshuttle")
			src.state = STATE_DEFAULT
			if(src.authenticated)
				src.state = STATE_CANCELSHUTTLE
		if("cancelshuttle2")
			if(src.authenticated)
				SSshuttle.cancelEvac(usr)
			src.state = STATE_DEFAULT
		if("messagelist")
			src.currmsg = 0
			src.state = STATE_MESSAGELIST
		if("viewmessage")
			src.state = STATE_VIEWMESSAGE
			if (!src.currmsg)
				if(href_list["message-num"])
					src.currmsg = text2num(href_list["message-num"])
				else
					src.state = STATE_MESSAGELIST
		if("delmessage")
			src.state = (src.currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
		if("delmessage2")
			if(src.authenticated)
				if(src.currmsg)
					var/title = src.messagetitle[src.currmsg]
					var/text  = src.messagetext[src.currmsg]
					src.messagetitle.Remove(title)
					src.messagetext.Remove(text)
					if(src.currmsg == src.aicurrmsg)
						src.aicurrmsg = 0
					src.currmsg = 0
				src.state = STATE_MESSAGELIST
			else
				src.state = STATE_VIEWMESSAGE
		if("status")
			src.state = STATE_STATUSDISPLAY

		if("securitylevel")
			src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
			if(!tmp_alertlevel) tmp_alertlevel = 0
			state = STATE_CONFIRM_LEVEL
		if("changeseclevel")
			state = STATE_ALERT_LEVEL

		if("emergencyaccess")
			state = STATE_TOGGLE_EMERGENCY
		if("enableemergency")
			make_maint_all_access()
			log_game("[key_name(usr)] enabled emergency maintenance access.")
			message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
			src.state = STATE_DEFAULT
		if("disableemergency")
			revoke_maint_all_access()
			log_game("[key_name(usr)] disabled emergency maintenance access.")
			message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
			src.state = STATE_DEFAULT

		// Status display stuff
		if("setstat")
			switch(href_list["statdisp"])
				if("message")
					post_status("message", stat_msg1, stat_msg2)
				if("alert")
					post_status("alert", href_list["alert"])
				else
					post_status(href_list["statdisp"])

		if("setmsg1")
			stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40)
			src.updateDialog()
		if("setmsg2")
			stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40)
			src.updateDialog()

		// OMG CENTCOM LETTERHEAD
		if("MessageCentcomm")
			if(src.authenticated==2)
				if(CM.cooldownLeft())
					usr << "Arrays recycling.  Please stand by."
					return
				var/input = stripped_input(usr, "Please choose a message to transmit to Centcom via quantum entanglement.  Please be aware that this process is very expensive, and abuse will lead to... termination.  Transmission does not guarantee a response.", "Send a message to Centcomm.", "")
				if(!input || !(usr in view(1,src)))
					return
				Centcomm_announce(input, usr)
				usr << "Message transmitted."
				log_say("[key_name(usr)] has made a Centcom announcement: [input]")
				CM.lastTimeUsed = world.time

		// OMG SYNDICATE ...LETTERHEAD
		if("MessageSyndicate")
			if((src.authenticated==2) && (src.emagged))
				if(CM.cooldownLeft())
					usr << "Arrays recycling.  Please stand by."
					return
				var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING COORDINATES\] via quantum entanglement.  Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to /??????/.", "")
				if(!input || !(usr in view(1,src)))
					return
				Syndicate_announce(input, usr)
				usr << "Message transmitted."
				log_say("[key_name(usr)] has made a Syndicate announcement: [input]")
				CM.lastTimeUsed = world.time

		if("RestoreBackup")
			usr << "Backup routing data restored!"
			src.emagged = 0
			src.updateDialog()

		if("nukerequest") //When there's no other way
			if(src.authenticated==2)
				if(CM.cooldownLeft())
					usr << "Arrays recycling. Please stand by."
					return
				var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances.  Transmission does not guarantee a response.", "Self Destruct Code Request.","")
				if(!input || !(usr in view(1,src)))
					return
				Nuke_request(input, usr)
				usr << "Request sent."
				log_say("[key_name(usr)] has requested the nuclear codes from Centcomm")
				priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/AI/commandreport.ogg')

				CM.lastTimeUsed = world.time

		// AI interface
		if("ai-main")
			src.aicurrmsg = 0
			src.aistate = STATE_DEFAULT
		if("ai-callshuttle")
			src.aistate = STATE_CALLSHUTTLE
		if("ai-callshuttle2")
			SSshuttle.requestEvac(usr, href_list["call"])
			src.aistate = STATE_DEFAULT
		if("ai-messagelist")
			src.aicurrmsg = 0
			src.aistate = STATE_MESSAGELIST
		if("ai-viewmessage")
			src.aistate = STATE_VIEWMESSAGE
			if (!src.aicurrmsg)
				if(href_list["message-num"])
					src.aicurrmsg = text2num(href_list["message-num"])
				else
					src.aistate = STATE_MESSAGELIST
		if("ai-delmessage")
			src.aistate = (src.aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
		if("ai-delmessage2")
			if(src.aicurrmsg)
				var/title = src.messagetitle[src.aicurrmsg]
				var/text  = src.messagetext[src.aicurrmsg]
				src.messagetitle.Remove(title)
				src.messagetext.Remove(text)
				if(src.currmsg == src.aicurrmsg)
					src.currmsg = 0
				src.aicurrmsg = 0
			src.aistate = STATE_MESSAGELIST
		if("ai-status")
			src.aistate = STATE_STATUSDISPLAY
		if("ai-announce")
			if(!ai_message_cooldown)
				make_announcement(usr, 1)
		if("ai-securitylevel")
			src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
			if(!tmp_alertlevel) tmp_alertlevel = 0
			var/old_level = security_level
			if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN
			if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN
			if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
			set_security_level(tmp_alertlevel)
			if(security_level != old_level)
				//Only notify the admins if an actual change happened
				log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
				message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
				switch(security_level)
					if(SEC_LEVEL_GREEN)
						feedback_inc("alert_comms_green",1)
					if(SEC_LEVEL_BLUE)
						feedback_inc("alert_comms_blue",1)
			tmp_alertlevel = 0
			src.aistate = STATE_DEFAULT
		if("ai-changeseclevel")
			src.aistate = STATE_ALERT_LEVEL

		if("ai-emergencyaccess")
			src.aistate = STATE_TOGGLE_EMERGENCY
		if("ai-enableemergency")
			make_maint_all_access()
			log_game("[key_name(usr)] enabled emergency maintenance access.")
			message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
			src.aistate = STATE_DEFAULT
		if("ai-disableemergency")
			revoke_maint_all_access()
			log_game("[key_name(usr)] disabled emergency maintenance access.")
			message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
			src.aistate = STATE_DEFAULT

	src.updateUsrDialog()

/obj/machinery/computer/communications/attackby(var/obj/I as obj, var/mob/user as mob, params)
	if(istype(I, /obj/item/weapon/card/id))
		attack_hand(user)
	else
		..()
	return

/obj/machinery/computer/communications/emag_act(mob/user as mob)
	if(!emagged)
		src.emagged = 1
		if(authenticated == 1)
			authenticated = 2
		user << "You scramble the communication routing circuits!"

/obj/machinery/computer/communications/attack_hand(var/mob/user as mob)
	if(..())
		return
	if (src.z > 6)
		user << "Unable to establish a connection: \black You're too far away from the station!"
		return

	user.set_machine(src)
	var/dat = ""
	if(SSshuttle.emergency.mode == SHUTTLE_CALL)
		var/timeleft = SSshuttle.emergency.timeLeft()
		dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]"

	var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))

	if (istype(user, /mob/living/silicon))
		var/dat2 = src.interact_ai(user) // give the AI a different interact proc to limit its access
		if(dat2)
			dat +=  dat2
			//user << browse(dat, "window=communications;size=400x500")
			//onclose(user, "communications")

			popup.set_content(dat)
			popup.open()
		return

	switch(src.state)
		if(STATE_DEFAULT)
			if (src.authenticated)
				if(SSshuttle.emergencyLastCallLoc)
					dat += "
Most recent shuttle call/recall traced to: [format_text(SSshuttle.emergencyLastCallLoc.name)]"
				else
					dat += "
Unable to trace most recent shuttle call/recall signal."
				dat += "
Logged in as: [auth_id]"
				dat += "
"
				dat += "
\[ Log Out \]
"
				dat += "
General Functions"
				dat += "
\[ Message List \]"
				switch(SSshuttle.emergency.mode)
					if(SHUTTLE_IDLE, SHUTTLE_RECALL)
						dat += "
\[ Call Emergency Shuttle \]"
					else
						dat += "
\[ Cancel Shuttle Call \]"

				dat += "
\[ Set Status Display \]"
				if (src.authenticated==2)
					dat += "

Captain Functions"
					dat += "
\[ Make a Captain's Announcement \]"
					dat += "
\[ Change Alert Level \]"
					dat += "
\[ Emergency Maintenance Access \]"
					dat += "
\[ Request Nuclear Authentication Codes \]"
					if(src.emagged == 0)
						dat += "
\[ Send Message to Centcom \]"
					else
						dat += "
\[ Send Message to \[UNKNOWN\] \]"
						dat += "
\[ Restore Backup Routing Data \]"
			else
				dat += "
\[ Log In \]"
		if(STATE_CALLSHUTTLE)
			dat += get_call_shuttle_form()
		if(STATE_CANCELSHUTTLE)
			dat += get_cancel_shuttle_form()
		if(STATE_MESSAGELIST)
			dat += "Messages:"
			for(var/i = 1; i<=src.messagetitle.len; i++)
				dat += "
[src.messagetitle[i]]"
		if(STATE_VIEWMESSAGE)
			if (src.currmsg)
				dat += "[src.messagetitle[src.currmsg]]

[src.messagetext[src.currmsg]]"
				if (src.authenticated)
					dat += "

\[ Delete \]"
			else
				src.state = STATE_MESSAGELIST
				src.attack_hand(user)
				return
		if(STATE_DELMESSAGE)
			if (src.currmsg)
				dat += "Are you sure you want to delete this message? \[ OK | Cancel \]"
			else
				src.state = STATE_MESSAGELIST
				src.attack_hand(user)
				return
		if(STATE_STATUSDISPLAY)
			dat += "Set Status Displays
"
			dat += "\[ Clear \]
"
			dat += "\[ Shuttle ETA \]
"
			dat += "\[ Message \]"
			dat += "

 Line 1: [ stat_msg1 ? stat_msg1 : "(none)"]"
			dat += "
 Line 2: [ stat_msg2 ? stat_msg2 : "(none)"]

"
			dat += "\[ Alert: None |"
			dat += " Red Alert |"
			dat += " Lockdown |"
			dat += " Biohazard \]

"
		if(STATE_ALERT_LEVEL)
			dat += "Current alert level: [get_security_level()]
"
			if(security_level == SEC_LEVEL_DELTA)
				dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate."
			else
				dat += "Blue
"
				dat += "Green"
		if(STATE_CONFIRM_LEVEL)
			dat += "Current alert level: [get_security_level()]
"
			dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]
"
			dat += "Swipe ID to confirm change.
"
		if(STATE_TOGGLE_EMERGENCY)
			if(emergency_access == 1)
				dat += "Emergency Maintenance Access is currently ENABLED"
				dat += "
Restore maintenance access restrictions?
\[ OK | Cancel \]"
			else
				dat += "Emergency Maintenance Access is currently DISABLED"
				dat += "
Lift access restrictions on maintenance and external airlocks?
\[ OK | Cancel \]"

	dat += "

\[ [(src.state != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]"
	//user << browse(dat, "window=communications;size=400x500")
	//onclose(user, "communications")
	popup.set_content(dat)
	popup.open()

/obj/machinery/computer/communications/proc/get_javascript_header(var/form_id)
	var/dat = {""}
	return dat

/obj/machinery/computer/communications/proc/get_call_shuttle_form(var/ai_interface = 0)
	var/form_id = "callshuttle"
	var/dat = get_javascript_header(form_id)
	dat += "<form name='callshuttle' id='[form_id]' action='?src=\ref[src]' method='get' style='display: inline'>"
	dat += "<input type='hidden' name='src' value='\ref[src]'>"
	dat += "<input type='hidden' name='operation' value='[ai_interface ? "ai-callshuttle2" : "callshuttle2"]'>"
	dat += "Nature of emergency:
 <input type='text' id='reasonfield' name='call' style='width:250px; background-color:#FFDDDD; onkeydown='getLength() onkeyup='getLength()' onkeypress='getLength()'>"
	dat += "
Are you sure you want to call the shuttle? \[ Call \]"
	return dat

/obj/machinery/computer/communications/proc/get_cancel_shuttle_form()
	var/form_id = "cancelshuttle"
	var/dat = get_javascript_header(form_id)
	dat += "<form name='cancelshuttle' id='[form_id]' action='?src=\ref[src]' method='get' style='display: inline'>"
	dat += "<input type='hidden' name='src' value='\ref[src]'>"
	dat += "<input type='hidden' name='operation' value='cancelshuttle2'>"

	dat += "
Are you sure you want to cancel the shuttle? \[ Cancel \]"
	return dat

/obj/machinery/computer/communications/proc/interact_ai(var/mob/living/silicon/ai/user as mob)
	var/dat = ""
	switch(src.aistate)
		if(STATE_DEFAULT)
			if(SSshuttle.emergencyLastCallLoc)
				dat += "
Latest emergency signal trace attempt successful.
Last signal origin: [format_text(SSshuttle.emergencyLastCallLoc.name)].
"
			else
				dat += "
Latest emergency signal trace attempt failed.
"
			if(authenticated)
				dat += "Current login: [auth_id]"
			else
				dat += "Current login: None"
			dat += "

General Functions"
			dat += "
\[ Message List \]"
			if(SSshuttle.emergency.mode <= SHUTTLE_IDLE)
				dat += "
\[ Call Emergency Shuttle \]"
			dat += "
\[ Set Status Display \]"
			dat += "

Special Functions"
			dat += "
\[ Make an Announcement \]"
			dat += "
\[ Change Alert Level \]"
			dat += "
\[ Emergency Maintenance Access \]"
		if(STATE_CALLSHUTTLE)
			dat += get_call_shuttle_form(1)
		if(STATE_MESSAGELIST)
			dat += "Messages:"
			for(var/i = 1; i<=src.messagetitle.len; i++)
				dat += "
[src.messagetitle[i]]"
		if(STATE_VIEWMESSAGE)
			if (src.aicurrmsg)
				dat += "[src.messagetitle[src.aicurrmsg]]

[src.messagetext[src.aicurrmsg]]"
				dat += "

\[ Delete \]"
			else
				src.aistate = STATE_MESSAGELIST
				src.attack_hand(user)
				return null
		if(STATE_DELMESSAGE)
			if(src.aicurrmsg)
				dat += "Are you sure you want to delete this message? \[ OK | Cancel \]"
			else
				src.aistate = STATE_MESSAGELIST
				src.attack_hand(user)
				return

		if(STATE_STATUSDISPLAY)
			dat += "Set Status Displays
"
			dat += "\[ Clear \]
"
			dat += "\[ Shuttle ETA \]
"
			dat += "\[ Message \]"
			dat += "

 Line 1: [ stat_msg1 ? stat_msg1 : "(none)"]"
			dat += "
 Line 2: [ stat_msg2 ? stat_msg2 : "(none)"]

"
			dat += "\[ Alert: None |"
			dat += " Red Alert |"
			dat += " Lockdown |"
			dat += " Biohazard \]

"

		if(STATE_ALERT_LEVEL)
			dat += "Current alert level: [get_security_level()]
"
			if(security_level == SEC_LEVEL_DELTA)
				dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate."
			else
				dat += "Blue
"
				dat += "Green"

		if(STATE_TOGGLE_EMERGENCY)
			if(emergency_access == 1)
				dat += "Emergency Maintenance Access is currently ENABLED"
				dat += "
Restore maintenance access restrictions?
\[ OK | Cancel \]"
			else
				dat += "Emergency Maintenance Access is currently DISABLED"
				dat += "
Lift access restrictions on maintenance and external airlocks?
\[ OK | Cancel \]"

	dat += "

\[ [(src.aistate != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]"
	return dat

/obj/machinery/computer/communications/proc/make_announcement(var/mob/living/user, var/is_silicon)
	var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?")
	if(!input || !user.canUseTopic(src))
		return
	if(is_silicon)
		minor_announce(input)
		ai_message_cooldown = 1
		spawn(600)//One minute cooldown
			ai_message_cooldown = 0
	else
		priority_announce(input, null, 'sound/misc/announce.ogg', "Captain")
		message_cooldown = 1
		spawn(600)//One minute cooldown
			message_cooldown = 0
	log_say("[key_name(user)] has made a priority announcement: [input]")
	message_admins("[key_name_admin(user)] has made a priority announcement.")

/obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2)

	var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435)

	if(!frequency) return

	var/datum/signal/status_signal = new
	status_signal.source = src
	status_signal.transmission_method = 1
	status_signal.data["command"] = command

	switch(command)
		if("message")
			status_signal.data["msg1"] = data1
			status_signal.data["msg2"] = data2
		if("alert")
			status_signal.data["picture_state"] = data1

	frequency.post_signal(src, status_signal)

/obj/machinery/computer/communications/Destroy()
	shuttle_caller_list -= src
	SSshuttle.autoEvac()
	..()


code:
/obj/machinery/computer
	name = "computer"
	icon = 'icons/obj/computer.dmi'
	density = 1
	anchored = 1.0
	use_power = 1
	idle_power_usage = 300
	active_power_usage = 300
	var/obj/item/weapon/circuitboard/circuit = null //if circuit==null, computer can't disassembly
	var/processing = 0
	use_auto_lights = 1
	light_power_on = 2
	light_range_on = 3

/obj/machinery/computer/New(location, obj/item/weapon/circuitboard/C)
	..(location)
	if(C && istype(C))
		circuit = C
	else
		if(circuit)
			circuit = new circuit(null)
	power_change()

/obj/machinery/computer/initialize()
	power_change()

/obj/machinery/computer/process()
	if(stat & (NOPOWER|BROKEN))
		return 0
	return 1

/obj/machinery/computer/emp_act(severity)
	if(prob(20/severity)) set_broken()
	..()

/obj/machinery/computer/ex_act(severity, target)
	if(target == src)
		qdel(src)
		return
	switch(severity)
		if(1.0)
			qdel(src)
			return
		if(2.0)
			if (prob(25))
				qdel(src)
				return
			if (prob(50))
				verbs.Cut()
				set_broken()
		if(3.0)
			if (prob(25))
				verbs.Cut()
				set_broken()
		else
	return

/obj/machinery/computer/bullet_act(var/obj/item/projectile/Proj)
	if(prob(Proj.damage))
		if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
			set_broken()
	..()

/obj/machinery/computer/blob_act()
	if (prob(75))
		verbs.Cut()
		set_broken()
		density = 0

/obj/machinery/computer/update_icon()
	..()
	icon_state = initial(icon_state)
	set_light(light_range_on, light_power_on)
	// Broken
	if(stat & BROKEN)
		icon_state += "b"

	// Unpowered
	else if(stat & NOPOWER)
		icon_state = initial(icon_state)
		icon_state += "0"
		set_light(0)

/obj/machinery/computer/power_change()
	..()
	update_icon()
	return

/obj/machinery/computer/proc/set_broken()
	if(circuit) //no circuit, no breaking
		stat |= BROKEN
		update_icon()
	return

/obj/machinery/computer/attackby(I as obj, user as mob, params)
	if(istype(I, /obj/item/weapon/screwdriver) && circuit)
		playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
		user << " You start to disconnect the monitor."
		if(do_after(user, 20))
			var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
			A.circuit = circuit
			A.anchored = 1
			circuit = null
			for (var/obj/C in src)
				C.loc = src.loc
			if (src.stat & BROKEN)
				user << " The broken glass falls out."
				new /obj/item/weapon/shard( src.loc )
				A.state = 3
				A.icon_state = "3"
			else
				user << " You disconnect the monitor."
				A.state = 4
				A.icon_state = "4"
			qdel(src)
	return

/obj/machinery/computer/attack_hand(user)
	. = ..()
	return

/obj/machinery/computer/attack_paw(mob/living/user)
	user.do_attack_animation(src)
	if(circuit)
		if(prob(10))
			user.visible_message("[user.name] smashes the [src.name] with its paws.",\
			"You smash the [src.name] with your paws.",\
			"You hear a smashing sound.")
			set_broken()
			return
	user.visible_message("[user.name] smashes against the [src.name] with its paws.",\
	"You smash against the [src.name] with your paws.",\
	"You hear a clicking sound.")

/obj/machinery/computer/attack_alien(mob/living/user)
	user.do_attack_animation(src)
	if(circuit)
		if(prob(80))
			user.visible_message("[user.name] smashes the [src.name] with its claws.",\
			"You smash the [src.name] with your claws.",\
			"You hear a smashing sound.")
			set_broken()
			return
	user.visible_message("[user.name] smashes against the [src.name] with its claws.",\
	"You smash against the [src.name] with your claws.",\
	"You hear a clicking sound.")

license: mit


code:
/obj/machinery/computer/crew
	name = "crew monitoring console"
	desc = "Used to monitor active health sensors built into most of the crew's uniforms."
	icon_state = "crew"
	use_power = 1
	idle_power_usage = 250
	active_power_usage = 500
	circuit = "/obj/item/weapon/circuitboard/crew"

/obj/machinery/computer/crew/attack_ai(mob/user)
	if(stat & (BROKEN|NOPOWER))
		return
	crewmonitor(user,src)

/obj/machinery/computer/crew/attack_hand(mob/user)
	if(..())
		return
	if(stat & (BROKEN|NOPOWER))
		return
	crewmonitor(user,src)

/obj/machinery/computer/crew/Topic(href, href_list)
	if(..()) return
	if (src.z > 6)
		usr << "Unable to establish a connection: \black You're too far away from the station!"
		return
	if( href_list["close"] )
		usr << browse(null, "window=crewcomp")
		usr.unset_machine()
		return
	if(href_list["update"])
		src.updateDialog()
		return

proc/crewmonitor(mob/user,var/atom/source)
	var/jobs[0]
	jobs["Captain"] = 00
	jobs["Head of Personnel"] = 50
	jobs["Head of Security"] = 10
	jobs["Warden"] = 11
	jobs["Security Officer"] = 12
	jobs["Detective"] = 13
	jobs["Chief Medical Officer"] = 20
	jobs["Chemist"] = 21
	jobs["Geneticist"] = 22
	jobs["Virologist"] = 23
	jobs["Medical Doctor"] = 24
	jobs["Research Director"] = 30
	jobs["Scientist"] = 31
	jobs["Roboticist"] = 32
	jobs["Chief Engineer"] = 40
	jobs["Station Engineer"] = 41
	jobs["Atmospheric Technician"] = 42
	jobs["Quartermaster"] = 51
	jobs["Shaft Miner"] = 52
	jobs["Cargo Technician"] = 53
	jobs["Bartender"] = 61
	jobs["Cook"] = 62
	jobs["Botanist"] = 63
	jobs["Librarian"] = 64
	jobs["Chaplain"] = 65
	jobs["Clown"] = 66
	jobs["Mime"] = 67
	jobs["Janitor"] = 68
	jobs["Lawyer"] = 69
	jobs["Admiral"] = 200
	jobs["Centcom Commander"] = 210
	jobs["Custodian"] = 211
	jobs["Medical Officer"] = 212
	jobs["Research Officer"] = 213
	jobs["Emergency Response Team Commander"] = 220
	jobs["Security Response Officer"] = 221
	jobs["Engineer Response Officer"] = 222
	jobs["Medical Response Officer"] = 223
	jobs["Assistant"] = 999	//Unknowns/custom jobs should appear after civilians, and before assistants

	var/t = "

Name

Vitals

Position

"
	var/list/logs = list()
	var/list/tracked = crewscan()
	var/turf/srcturf = get_turf(source)
	for(var/mob/living/carbon/human/H in tracked)
		var/log = ""
		var/turf/pos = get_turf(H)
		if(istype(H.w_uniform, /obj/item/clothing/under))
			var/obj/item/clothing/under/U = H.w_uniform
			if(pos && pos.z == srcturf.z && U.sensor_mode)
				var/obj/item/weapon/card/id/I = null
				if(H.wear_id)
					I = H.wear_id.GetID()

				var/life_status = "[H.stat > 1 ? "Deceased" : "Living"]"

				if(I)
					var/style = null
					var/ijob = jobs[I.assignment]
					if(ijob % 10 == 0)
						style += "font-weight: bold; "	//head roles always end in 0
					if(ijob >= 10 && ijob < 20)
						style += "color: #E74C3C; "	//security
					if(ijob >= 20 && ijob < 30)
						style += "color: #3498DB; "	//medical
					if(ijob >= 30 && ijob < 40)
						style += "color: #9B59B6; "	//science
					if(ijob >= 40 && ijob < 50)
						style += "color: #F1C40F; "	//engineering
					if(ijob >= 50 && ijob < 60)
						style += "color: #F39C12; "	//cargo
					if(ijob >= 200 && ijob < 230)
						style += "color: #00C100; "	//Centcom
					log += "[ijob]]
[I.registered_name] ([I.assignment])	"		//ijob does not get displayed, nor does it take up space, it's just used for the positioning of an entry
				else
					log += "80
Unknown	"

				var/damage_report
				if(U.sensor_mode > 1)
					var/dam1 = round(H.getOxyLoss(),1)
					var/dam2 = round(H.getToxLoss(),1)
					var/dam3 = round(H.getFireLoss(),1)
					var/dam4 = round(H.getBruteLoss(),1)
					damage_report = "([dam1]/[dam2]/[dam3]/[dam4])"

				switch(U.sensor_mode)
					if(1)
						log += "[life_status]	Not Available
"
					if(2)
						log += "[life_status] [damage_report]	Not Available
"
					if(3)
						var/area/player_area = get_area(H)
						log += "[life_status] [damage_report]	[format_text(player_area.name)] ([pos.x], [pos.y])
"
		logs += log
	logs = sortList(logs)
	for(var/log in logs)
		t += log
	t += "
"
	var/datum/browser/popup = new(user, "crewcomp", "Crew Monitoring", 900, 600)
	popup.set_content(t)
	popup.open()

proc/crewscan()
	var/list/tracked = list()
	for(var/mob/living/carbon/human/H in mob_list)
		if(istype(H.w_uniform, /obj/item/clothing/under))
			var/obj/item/clothing/under/U = H.w_uniform
			if(U.has_sensor && U.sensor_mode)
				tracked.Add(H)
	return tracked


code:
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31

/obj/machinery/computer/upload
	var/mob/living/silicon/current = null //The target of future law uploads
	icon_state = null //To make sure mappers understand THIS ISN'T A VALID TYPE

/obj/machinery/computer/upload/attackby(obj/item/O as obj, mob/user as mob, params)
	if(istype(O, /obj/item/weapon/aiModule))
		var/obj/item/weapon/aiModule/M = O
		if(src.stat & (NOPOWER|BROKEN|MAINT))
			return
		if(!current)
			user << "You haven't selected anything to transmit laws to!"
			return
		if(!can_upload_to(current))
			user << "Upload failed! Check to make sure [current.name] is functioning properly."
			current = null
			return
		var/turf/currentloc = get_turf(current)
		if(currentloc && user.z != currentloc.z)
			user << "Upload failed! Unable to establish a connection to [current.name]. You're too far away!"
			current = null
			return
		M.install(current, user)
	else
		..()

/obj/machinery/computer/upload/proc/can_upload_to(var/mob/living/silicon/S as mob)
	if(S.stat == DEAD || S.syndicate)
		return 0
	return 1

/obj/machinery/computer/upload/ai
	name = "\improper AI upload console"
	desc = "Used to upload laws to the AI."
	icon_state = "command"
	circuit = /obj/item/weapon/circuitboard/aiupload

/obj/machinery/computer/upload/ai/attack_hand(var/mob/user as mob)
	if(..())
		return

	src.current = select_active_ai(user)

	if (!src.current)
		user << "No active AIs detected."
	else
		user << "[src.current.name] selected for law changes."

/obj/machinery/computer/upload/ai/can_upload_to(var/mob/living/silicon/ai/A as mob)
	if(!A || !isAI(A))
		return 0
	if(A.control_disabled)
		return 0
	return ..()

/obj/machinery/computer/upload/borg
	name = "cyborg upload console"
	desc = "Used to upload laws to Cyborgs."
	icon_state = "command"
	circuit = /obj/item/weapon/circuitboard/borgupload

/obj/machinery/computer/upload/borg/attack_hand(var/mob/user as mob)
	if(..())
		return

	src.current = select_active_free_borg(user)

	if(!src.current)
		user << "No active unslaved cyborgs detected."
	else
		user << "[src.current.name] selected for law changes."

/obj/machinery/computer/upload/borg/can_upload_to(var/mob/living/silicon/robot/B as mob)
	if(!B || !isrobot(B))
		return 0
	if(B.scrambledcodes || B.emagged)
		return 0
	return ..()


code:
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31

/obj/machinery/computer/med_data//TODO:SANITY
	name = "medical records console"
	desc = "This can be used to check medical records."
	icon_state = "medcomp"
	req_one_access = list(access_medical, access_forensics_lockers)
	circuit = /obj/item/weapon/circuitboard/med_data
	var/obj/item/weapon/card/id/scan = null
	var/authenticated = null
	var/rank = null
	var/screen = null
	var/datum/data/record/active1
	var/datum/data/record/active2
	var/a_id = null
	var/temp = null
	var/printing = null
	//Sorting Variables
	var/sortBy = "name"
	var/order = 1 // -1 = Descending - 1 = Ascending

/obj/machinery/computer/med_data/attackby(obj/item/O as obj, user as mob, params)
	if(istype(O, /obj/item/weapon/card/id) && !scan)
		usr.drop_item()
		O.loc = src
		scan = O
		user << "You insert [O]."
	else
		..()

/obj/machinery/computer/med_data/attack_hand(mob/user as mob)
	if(..())
		return
	var/dat
	if(src.temp)
		dat = text("<TT>[src.temp]</TT>

Clear Screen")
	else
		dat = text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------"))
		if(src.authenticated)
			switch(src.screen)
				if(1.0)
					dat += {"
Search Records

List Records

Virus Database

Medbot Tracking

Record Maintenance

{Log Out}

"}
				if(2.0)
					dat += {"

Records:

Name
ID
Fingerprints (F) | DNA (D)
Blood Type
Physical Status
Mental Status

"}

					if(!isnull(data_core.general))
						for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order))
							var/blood_type = ""
							var/b_dna = ""
							for(var/datum/data/record/E in data_core.medical)
								if((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
									blood_type = E.fields["blood_type"]
									b_dna = E.fields["b_dna"]
							var/background

							if(R.fields["m_stat"] == "*Insane*" || R.fields["p_stat"] == "*Deceased*")
								background = "'background-color:#990000;'"
							else if(R.fields["p_stat"] == "*Unconscious*" || R.fields["m_stat"] == "*Unstable*")
								background = "'background-color:#CD6500;'"
							else if(R.fields["p_stat"] == "Physically Unfit" || R.fields["m_stat"] == "*Watch*")
								background = "'background-color:#3BB9FF;'"
							else
								background = "'background-color:#4F7529;'"

							dat += text("
[]	", background, src, R.fields["id"], R.fields["name"])
							dat += text("[]	", R.fields["id"])
							dat += text("F: []
D: []	", R.fields["fingerprint"], b_dna)
							dat += text("[]	", blood_type)
							dat += text("[]	", R.fields["p_stat"])
							dat += text("[]
", R.fields["m_stat"])
					dat += "

"
//					if(data_core.general)
//						for(var/datum/data/record/R in sortRecord(data_core.general))
//							dat += "[R.fields["id"]]: [R.fields["name"]]
"
//							//Foreach goto(132)
					dat += text("
Back", src)
				if(3.0)
					dat += text("Records Maintenance
\nBackup To Disk
\nUpload From Disk
\nDelete All Records
\n
\nBack", src, src, src, src)
				if(4.0)

					dat += "

Medical Record
"
					if(active1 in data_core.general)
						if(istype(active1.fields["photo_front"], /obj/item/weapon/photo))
							var/obj/item/weapon/photo/P1 = active1.fields["photo_front"]
							user << browse_rsc(P1.img, "photo_front")
						if(istype(active1.fields["photo_side"], /obj/item/weapon/photo))
							var/obj/item/weapon/photo/P2 = active1.fields["photo_side"]
							user << browse_rsc(P2.img, "photo_side")
						dat += "
Name:	[active1.fields["name"]]	"
						dat += "	"
						dat += "
"
						dat += "
ID:	[active1.fields["id"]]
"
						dat += "
Sex:	 [active1.fields["sex"]]
"
						dat += "
Age:	 [active1.fields["age"]]
"
						if(config.mutant_races)
							dat += "
Species:	 [active1.fields["species"]]
"
						dat += "
Fingerprint:	 [active1.fields["fingerprint"]]
"
						dat += "
Physical Status:	 [active1.fields["p_stat"]]
"
						dat += "
Mental Status:	 [active1.fields["m_stat"]]
"
					else
						dat += "
General Record Lost!
"

					dat += "

Medical Data
"
					if(active2 in data_core.medical)
						dat += "
Blood Type:	 [active2.fields["blood_type"]]
"
						dat += "
DNA:	 [active2.fields["b_dna"]]
"
						dat += "

Minor Disabilities:
 [active2.fields["mi_dis"]]
"
						dat += "
Details:	 [active2.fields["mi_dis_d"]]
"
						dat += "

Major Disabilities:
 [active2.fields["ma_dis"]]
"
						dat += "
Details:	 [active2.fields["ma_dis_d"]]
"
						dat += "

Allergies:
 [active2.fields["alg"]]
"
						dat += "
Details:	 [active2.fields["alg_d"]]
"
						dat += "

Current Diseases:
 [active2.fields["cdi"]]
" //(per disease info placed in log/comment section)
						dat += "
Details:	 [active2.fields["cdi_d"]]
"
						dat += "

Important Notes:
 [active2.fields["notes"]]
"

						dat += "

Comments/Log
"
						var/counter = 1
						while(src.active2.fields[text("com_[]", counter)])
							dat += "
[active2.fields[text("com_[]", counter)]]

Delete Entry
"
							counter++
						dat += "
Add Entry
"

						dat += "

Delete Record (Medical Only)
"
					else
						dat += "
Medical Record Lost!
"
						dat += "

New Record
"
					dat += "
Print Record
"
					dat += "
Back
"
					dat += "
"
				if(5.0)
					dat += "Virus Database"
					for(var/Dt in typesof(/datum/disease/))
						var/datum/disease/Dis = new Dt(0)
						if(istype(Dis, /datum/disease/advance))
							continue // TODO (tm): Add advance diseases to the virus database which no one uses.
						if(!Dis.desc)
							continue
						dat += "
[Dis.name]"
					dat += "
Back"
				if(6.0)
					dat += "Medical Robot Monitor"
					dat += "Back"
					dat += "
Medical Robots:"
					var/bdat = null
					for(var/obj/machinery/bot/medbot/M in world)
						if(M.z != src.z)	continue	//only find medibots on the same z-level as the computer
						var/turf/bl = get_turf(M)
						if(bl)	//if it can't find a turf for the medibot, then it probably shouldn't be showing up
							bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
"
							if((!isnull(M.reagent_glass)) && M.use_beaker)
								bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]
"
							else
								bdat += "Using Internal Synthesizer.
"

					if(!bdat)
						dat += "
None detected"
					else
						dat += "
[bdat]"

				else
		else
			dat += text("{Log In}", src)
	//user << browse(text("<TITLE>Medical Records</TITLE><TT>[]</TT>", dat), "window=med_rec")
	//onclose(user, "med_rec")
	var/datum/browser/popup = new(user, "med_rec", "Medical Records Console", 600, 400)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

/obj/machinery/computer/med_data/Topic(href, href_list)
	. = ..()
	if(.)
		return .
	if(!(active1 in data_core.general))
		src.active1 = null
	if(!(active2 in data_core.medical))
		src.active2 = null

	if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
		usr.set_machine(src)
		if(href_list["temp"])
			src.temp = null
		if(href_list["scan"])
			if(src.scan)
				src.scan.loc = src.loc
				src.scan = null
			else
				var/obj/item/I = usr.get_active_hand()
				if(istype(I, /obj/item/weapon/card/id))
					usr.drop_item()
					I.loc = src
					src.scan = I
		else if(href_list["logout"])
			src.authenticated = null
			src.screen = null
			src.active1 = null
			src.active2 = null
		else if(href_list["choice"])
			// SORTING!
			if(href_list["choice"] == "Sorting")
				// Reverse the order if clicked twice
				if(sortBy == href_list["sort"])
					if(order == 1)
						order = -1
					else
						order = 1
				else
				// New sorting order!
					sortBy = href_list["sort"]
					order = initial(order)
		else if(href_list["login"])
			if(istype(usr, /mob/living/silicon))
				src.active1 = null
				src.active2 = null
				src.authenticated = 1
				src.rank = "AI"
				src.screen = 1
			else if(istype(src.scan, /obj/item/weapon/card/id))
				src.active1 = null
				src.active2 = null
				if(src.check_access(src.scan))
					src.authenticated = src.scan.registered_name
					src.rank = src.scan.assignment
					src.screen = 1
		if(src.authenticated)

			if(href_list["screen"])
				src.screen = text2num(href_list["screen"])
				if(src.screen < 1)
					src.screen = 1

				src.active1 = null
				src.active2 = null

			else if(href_list["vir"])
				var/type = href_list["vir"]
				var/datum/disease/Dis = new type(0)
				var/AfS = ""
				for(var/mob/M in Dis.viable_mobtypes)
					AfS += " [initial(M.name)];"
				src.temp = {"Name: [Dis.name]

Number of stages: [Dis.max_stages]

Spread: [Dis.spread_text] Transmission

Possible Cure: [(Dis.cure_text||"none")]

Affected Lifeforms:[AfS]

Notes: [Dis.desc]

Severity: [Dis.severity]"}

			else if(href_list["del_all"])
				src.temp = text("Are you sure you wish to delete all records?
\n\tYes
\n\tNo
", src, src)

			else if(href_list["del_all2"])
				investigate_log("[usr.name] ([usr.key]) has deleted all medical records.", "records")
				data_core.medical.Cut()
				src.temp = "All records deleted."

			else if(href_list["field"])
				var/a1 = src.active1
				var/a2 = src.active2
				switch(href_list["field"])
					if("fingerprint")
						if(active1)
							var/t1 = copytext(sanitize(input("Search String: (Name, DNA, or ID)", "Med. records", null, null)  as text),1,MAX_MESSAGE_LEN)
							if(!canUseMedicalRecordsConsole(usr, t1, a1))
								return
							src.active1.fields["fingerprint"] = t1
					if("sex")
						if(active1)
							if(src.active1.fields["sex"] == "Male")
								src.active1.fields["sex"] = "Female"
							else
								src.active1.fields["sex"] = "Male"
					if("age")
						if(active1)
							var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null)  as num
							if(!canUseMedicalRecordsConsole(usr, t1, a1))
								return
							src.active1.fields["age"] = t1
					if("species")
						if(active1)
							var/t1 = stripped_input("Please input species name", "Med. records", src.active1.fields["species"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, a1))
								return
							active1.fields["species"] = t1
					if("mi_dis")
						if(active2)
							var/t1 = stripped_input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["mi_dis"] = t1
					if("mi_dis_d")
						if(active2)
							var/t1 = stripped_multiline_input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["mi_dis_d"] = t1
					if("ma_dis")
						if(active2)
							var/t1 = stripped_input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["ma_dis"] = t1
					if("ma_dis_d")
						if(active2)
							var/t1 = stripped_multiline_input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["ma_dis_d"] = t1
					if("alg")
						if(active2)
							var/t1 = stripped_input("Please state allergies:", "Med. records", src.active2.fields["alg"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["alg"] = t1
					if("alg_d")
						if(active2)
							var/t1 = stripped_multiline_input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["alg_d"] = t1
					if("cdi")
						if(active2)
							var/t1 = stripped_input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["cdi"] = t1
					if("cdi_d")
						if(active2)
							var/t1 = stripped_multiline_input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["cdi_d"] = t1
					if("notes")
						if(active2)
							var/t1 = stripped_multiline_input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["notes"] = t1
					if("p_stat")
						if(active1)
							src.temp = text("Physical Condition:
\n\t*Deceased*
\n\t*Unconscious*
\n\tActive
\n\tPhysically Unfit
", src, src, src, src)
					if("m_stat")
						if(active1)
							src.temp = text("Mental Condition:
\n\t*Insane*
\n\t*Unstable*
\n\t*Watch*
\n\tStable
", src, src, src, src)
					if("blood_type")
						if(active2)
							src.temp = text("Blood Type:
\n\tA- A+
\n\tB- B+
\n\tAB- AB+
\n\tO- O+
", src, src, src, src, src, src, src, src)
					if("b_dna")
						if(active2)
							var/t1 = stripped_input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null)
							if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
								return
							src.active2.fields["b_dna"] = t1
					if("show_photo_front")
						if(active1)
							if(active1.fields["photo_front"])
								if(istype(active1.fields["photo_front"], /obj/item/weapon/photo))
									var/obj/item/weapon/photo/P = active1.fields["photo_front"]
									P.show(usr)
					if("show_photo_side")
						if(active1)
							if(active1.fields["photo_side"])
								if(istype(active1.fields["photo_side"], /obj/item/weapon/photo))
									var/obj/item/weapon/photo/P = active1.fields["photo_side"]
									P.show(usr)
					else

			else if(href_list["p_stat"])
				if(active1)
					switch(href_list["p_stat"])
						if("deceased")
							src.active1.fields["p_stat"] = "*Deceased*"
						if("unconscious")
							src.active1.fields["p_stat"] = "*Unconscious*"
						if("active")
							src.active1.fields["p_stat"] = "Active"
						if("unfit")
							src.active1.fields["p_stat"] = "Physically Unfit"

			else if(href_list["m_stat"])
				if(active1)
					switch(href_list["m_stat"])
						if("insane")
							src.active1.fields["m_stat"] = "*Insane*"
						if("unstable")
							src.active1.fields["m_stat"] = "*Unstable*"
						if("watch")
							src.active1.fields["m_stat"] = "*Watch*"
						if("stable")
							src.active1.fields["m_stat"] = "Stable"

			else if(href_list["blood_type"])
				if(active2)
					switch(href_list["blood_type"])
						if("an")
							src.active2.fields["blood_type"] = "A-"
						if("bn")
							src.active2.fields["blood_type"] = "B-"
						if("abn")
							src.active2.fields["blood_type"] = "AB-"
						if("on")
							src.active2.fields["blood_type"] = "O-"
						if("ap")
							src.active2.fields["blood_type"] = "A+"
						if("bp")
							src.active2.fields["blood_type"] = "B+"
						if("abp")
							src.active2.fields["blood_type"] = "AB+"
						if("op")
							src.active2.fields["blood_type"] = "O+"

			else if(href_list["del_r"])
				if(active2)
					src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?
\n\tYes
\n\tNo
", src, src)

			else if(href_list["del_r2"])
				investigate_log("[usr.name] ([usr.key]) has deleted the medical records for [active1.fields["name"]].", "records")
				if(active2)
					data_core.medical -= active2
					active2 = null

			else if(href_list["d_rec"])
				active1 = find_record("id", href_list["d_rec"], data_core.general)
				if(active1)
					active2 = find_record("id", href_list["d_rec"], data_core.medical)
				if(!active2)
					active1 = null
				screen = 4

			else if(href_list["new"])
				if((istype(src.active1, /datum/data/record) && !( istype(src.active2, /datum/data/record) )))
					var/datum/data/record/R = new /datum/data/record(  )
					R.fields["name"] = src.active1.fields["name"]
					R.fields["id"] = src.active1.fields["id"]
					R.name = text("Medical Record #[]", R.fields["id"])
					R.fields["blood_type"] = "Unknown"
					R.fields["b_dna"] = "Unknown"
					R.fields["mi_dis"] = "None"
					R.fields["mi_dis_d"] = "No minor disabilities have been diagnosed."
					R.fields["ma_dis"] = "None"
					R.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
					R.fields["alg"] = "None"
					R.fields["alg_d"] = "No allergies have been detected in this patient."
					R.fields["cdi"] = "None"
					R.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
					R.fields["notes"] = "No notes."
					data_core.medical += R
					src.active2 = R
					src.screen = 4

			else if(href_list["add_c"])
				if(!(active2 in data_core.medical))
					return
				var/a2 = src.active2
				var/t1 = stripped_multiline_input("Add Comment:", "Med. records", null, null)
				if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
					return
				var/counter = 1
				while(src.active2.fields[text("com_[]", counter)])
					counter++
				src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
[]", src.authenticated, src.rank, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1,)

			else if(href_list["del_c"])
				if((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
					src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted"

			else if(href_list["search"])
				var/t1 = stripped_input(usr, "Search String: (Name, DNA, or ID)", "Med. records")
				if(!canUseMedicalRecordsConsole(usr, t1))
					return
				src.active1 = null
				src.active2 = null
				t1 = lowertext(t1)
				for(var/datum/data/record/R in data_core.medical)
					if((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"])))
						src.active2 = R
					else
						//Foreach continue //goto(3229)
				if(!( src.active2 ))
					src.temp = text("Could not locate record [].", sanitize(t1))
				else
					for(var/datum/data/record/E in data_core.general)
						if((E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"]))
							src.active1 = E
						else
							//Foreach continue //goto(3334)
					src.screen = 4

			else if(href_list["print_p"])
				if(!( src.printing ))
					src.printing = 1
					data_core.medicalPrintCount++
					playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1)
					sleep(30)
					var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.loc )
					P.info = "Medical Record - (MR-[data_core.medicalPrintCount])
"
					if(active1 in data_core.general)
						P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
", src.active1.fields["name"], src.active1.fields["id"], src.active1.fields["sex"], src.active1.fields["age"])
						if(config.mutant_races)
							P.info += "\nSpecies: [active1.fields["species"]]
"
						P.info += text("\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", src.active1.fields["fingerprint"], src.active1.fields["p_stat"], src.active1.fields["m_stat"])
					else
						P.info += "General Record Lost!
"
					if(active2 in data_core.medical)
						P.info += text("
\nMedical Data
\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\nComments/Log
", src.active2.fields["blood_type"], src.active2.fields["b_dna"], src.active2.fields["mi_dis"], src.active2.fields["mi_dis_d"], src.active2.fields["ma_dis"], src.active2.fields["ma_dis_d"], src.active2.fields["alg"], src.active2.fields["alg_d"], src.active2.fields["cdi"], src.active2.fields["cdi_d"], src.active2.fields["notes"])
						var/counter = 1
						while(src.active2.fields[text("com_[]", counter)])
							P.info += text("[]
", src.active2.fields[text("com_[]", counter)])
							counter++
						P.name = text("MR-[] '[]'", data_core.medicalPrintCount, src.active1.fields["name"])
					else
						P.info += "Medical Record Lost!
"
						P.name = text("MR-[] '[]'", data_core.medicalPrintCount, "Record Lost")
					P.info += "</TT>"
					src.printing = null

	src.add_fingerprint(usr)
	src.updateUsrDialog()
	return

/obj/machinery/computer/med_data/emp_act(severity)
	if(stat & (BROKEN|NOPOWER))
		..(severity)
		return

	for(var/datum/data/record/R in data_core.medical)
		if(prob(10/severity))
			switch(rand(1,6))
				if(1)
					R.fields["name"] = random_name(R.fields["sex"],1)
				if(2)
					R.fields["sex"]	= pick("Male", "Female")
				if(3)
					R.fields["age"] = rand(AGE_MIN, AGE_MAX)
				if(4)
					R.fields["blood_type"] = random_blood_type()
				if(5)
					R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit")
				if(6)
					R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
			continue

		else if(prob(1))
			del(R)
			continue

	..(severity)

/obj/machinery/computer/med_data/proc/canUseMedicalRecordsConsole(mob/user, message = 1, record1, record2)
	if(user)
		if(message)
			if(authenticated)
				if(user.canUseTopic(src))
					if(!record1 || record1 == active1)
						if(!record2 || record2 == active2)
							return 1
	return 0

/obj/machinery/computer/med_data/laptop
	name = "medical laptop"
	desc = "A cheap Nanotrasen medical laptop, it functions as a medical records computer. It's bolted to the table."
	icon_state = "medlaptop"


code:
// Allows you to monitor messages that passes the server.

/obj/machinery/computer/message_monitor
	name = "message monitor console"
	desc = "Used to Monitor the crew's messages, that are sent via PDA. Can also be used to view Request Console messages."
	icon_state = "comm_logs"
	var/hack_icon = "comm_logsc"
	var/normal_icon = "comm_logs"
	circuit = /obj/item/weapon/circuitboard/message_monitor
	//Server linked to.
	var/obj/machinery/message_server/linkedServer = null
	//Sparks effect - For emag
	var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
	//Messages - Saves me time if I want to change something.
	var/noserver = "ALERT: No server detected."
	var/incorrectkey = "ALERT: Incorrect decryption key!"
	var/defaultmsg = "Welcome. Please select an option."
	var/rebootmsg = "%$&(�: Critical %$$@ Error // !RestArting! <lOadiNg backUp iNput ouTput> - ?pLeaSe wAit!"
	//Computer properties
	var/screen = 0 		// 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
	var/hacking = 0		// Is it being hacked into by the AI/Cyborg
	var/emag = 0		// When it is emagged.
	var/message = "System bootup complete. Please select an option."	// The message that shows on the main menu.
	var/auth = 0 // Are they authenticated?
	var/optioncount = 7
	// Custom Message Properties
	var/customsender = "System Administrator"
	var/obj/item/device/pda/customrecepient = null
	var/customjob		= "Admin"
	var/custommessage 	= "This is a test, please ignore."

/obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/living/user as mob, params)
	if(stat & (NOPOWER|BROKEN))
		return
	if(!istype(user))
		return
	if(istype(O, /obj/item/weapon/screwdriver) && emag)
		//Stops people from just unscrewing the monitor and putting it back to get the console working again.
		user << "It is too hot to mess with!"
		return

	..()
	return

/obj/machinery/computer/message_monitor/emag_act(user as mob)
	if(!emag)
		if(!isnull(src.linkedServer))
			icon_state = hack_icon // An error screen I made in the computers.dmi
			emag = 1
			screen = 2
			spark_system.set_up(5, 0, src)
			src.spark_system.start()
			var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
			MK.loc = src.loc
			// Will help make emagging the console not so easy to get away with.
			MK.info += "

�%@%(*$%&(�&?*(%&�/{}"
			spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
			message = rebootmsg
		else
			user << "A no server error appears on the screen."

/obj/machinery/computer/message_monitor/update_icon()
	..()
	if(stat & (NOPOWER|BROKEN))
		return
	if(emag || hacking)
		icon_state = hack_icon
	else
		icon_state = normal_icon

/obj/machinery/computer/message_monitor/initialize()
	//Is the server isn't linked to a server, and there's a server available, default it to the first one in the list.
	if(!linkedServer)
		if(message_servers && message_servers.len > 0)
			linkedServer = message_servers[1]
	return

/obj/machinery/computer/message_monitor/attack_hand(var/mob/living/user as mob)
	if(..())
		return
	//If the computer is being hacked or is emagged, display the reboot message.
	if(hacking || emag)
		message = rebootmsg
	var/dat = "<font color='blue'[message]/"

	if(auth)
		dat += "

	\[Authenticated\]	/"
		dat += " Server Power: [src.linkedServer && src.linkedServer.active ? "\[On\]":"\[Off\]"]
"
	else
		dat += "

	\[Unauthenticated\]	/"
		dat += " Server Power: [src.linkedServer && src.linkedServer.active ? "\[On\]":"\[Off\]"]
"

	if(hacking || emag)
		screen = 2
	else if(!auth || !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
		if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) message = noserver
		screen = 0

	switch(screen)
		//Main menu
		if(0)
			//	 = TAB
			var/i = 0
			dat += "
	[++i]. Link To A Server
"
			if(auth)
				if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
					dat += "
	ERROR: Server not found!

"
				else
					dat += "
	[++i]. View Message Logs

"
					dat += "
	[++i]. View Request Console Logs

"
					dat += "
	[++i]. View Chatroom Logs

"
					dat += "
	[++i]. Clear Message Logs

"
					dat += "
	[++i]. Clear Request Console Logs

"
					dat += "
	[++i]. Clear Chatroom Logs

"
					dat += "
	[++i]. Set Custom Key

"
					dat += "
	[++i]. Send Admin Message

"
			else
				for(var/n = ++i; n <= optioncount; n++)
					dat += "
	[n]. ---------------

"
			if(issilicon(usr) && is_special_character(usr))
				//Malf/Traitor AIs can bruteforce into the system to gain the Key.
				dat += "
*&@#. Bruteforce Key

"
			else
				dat += "
"

			//Bottom message
			if(!auth)
				dat += "

Please authenticate with the server in order to show additional options."
			else
				dat += "

Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties."

		//Message Logs
		if(1)
			var/index = 0
			//var/recipient = "Unspecified" //name of the person
			//var/sender = "Unspecified" //name of the sender
			//var/message = "Blank" //transferred message
			dat += "Back - Refresh
"
			dat += "

X	Sender	Recipient	Message
"
			for(var/datum/data_pda_msg/pda in src.linkedServer.pda_msgs)
				index++
				if(index > 3000)
					break
				// Del - Sender   - Recepient - Message
				// X   - Al Green - Your Mom  - WHAT UP!?
				dat += "
X	[pda.sender]	[pda.recipient]	[pda.message]
"
			dat += "
"
		//Hacking screen.
		if(2)
			if(istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot))
				dat += "Brute-forcing for server key.
 It will take 20 seconds for every character that the password has."
				dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time."
			else
				//It's the same message as the one above but in binary. Because robots understand binary and humans don't... well I thought it was clever.
				dat += {"01000010011100100111010101110100011001010010110

				10110011001101111011100100110001101101001011011100110011

				10010000001100110011011110111001000100000011100110110010

				10111001001110110011001010111001000100000011010110110010

				10111100100101110001000000100100101110100001000000111011

				10110100101101100011011000010000001110100011000010110101

				10110010100100000001100100011000000100000011100110110010

				10110001101101111011011100110010001110011001000000110011

				00110111101110010001000000110010101110110011001010111001

				00111100100100000011000110110100001100001011100100110000

				10110001101110100011001010111001000100000011101000110100

				00110000101110100001000000111010001101000011001010010000

				00111000001100001011100110111001101110111011011110111001

				00110010000100000011010000110000101110011001011100010000

				00100100101101110001000000111010001101000011001010010000

				00110110101100101011000010110111001110100011010010110110

				10110010100101100001000000111010001101000011010010111001

				10010000001100011011011110110111001110011011011110110110

				00110010100100000011000110110000101101110001000000111001

				00110010101110110011001010110000101101100001000000111100

				10110111101110101011100100010000001110100011100100111010

				10110010100100000011010010110111001110100011001010110111

				00111010001101001011011110110111001110011001000000110100

				10110011000100000011110010110111101110101001000000110110

				00110010101110100001000000111001101101111011011010110010

				10110111101101110011001010010000001100001011000110110001

				10110010101110011011100110010000001101001011101000010111

				00010000001001101011000010110101101100101001000000111001

				10111010101110010011001010010000001101110011011110010000

				00110100001110101011011010110000101101110011100110010000

				00110010101101110011101000110010101110010001000000111010

				00110100001100101001000000111001001101111011011110110110

				10010000001100100011101010111001001101001011011100110011

				10010000001110100011010000110000101110100001000000111010

				001101001011011010110010100101110"}

		//Fake messages
		if(3)
			dat += "Back - Reset
"

			dat += {"

Sender
					Sender's Job
					Recipient
					Message
"}
				//Sender  - Sender's Job  - Recepient - Message
				//Al Green- Your Dad	  - Your Mom  - WHAT UP!?

			dat += {"
[customsender]
			[customjob]
			[customrecepient ? customrecepient.owner : "NONE"]
			[custommessage]
"}
			dat += "

Send"

		//Request Console Logs
		if(4)

			var/index = 0
			/* 	data_rc_msg
				X												 - 5%
				var/rec_dpt = "Unspecified" //name of the person - 15%
				var/send_dpt = "Unspecified" //name of the sender- 15%
				var/message = "Blank" //transferred message		 - 300px
				var/stamp = "Unstamped"							 - 15%
				var/id_auth = "Unauthenticated"					 - 15%
				var/priority = "Normal"							 - 10%
			*/
			dat += "Back - Refresh
"
			dat += {"

X	Sending Dep.	Receiving Dep.
			Message	Stamp	ID Auth.	Priority.
"}
			for(var/datum/data_rc_msg/rc in src.linkedServer.rc_msgs)
				index++
				if(index > 3000)
					break
				// Del - Sender   - Recepient - Message
				// X   - Al Green - Your Mom  - WHAT UP!?
				dat += {"
X	[rc.send_dpt]
				[rc.rec_dpt]	[rc.message]	[rc.stamp]	[rc.id_auth]	[rc.priority]
"}
			dat += "
"

		//Chatroom Logs
		if(5)

			var/index = 0
			//var/sender = "Anon"
			//var/channel = "ss13"
			//var/message = "Blank"
			dat += "Back - Refresh
"
			dat += "

X	Channel	Nick	Message
"
			for(var/datum/data_chat_msg/msg in src.linkedServer.chat_msgs)
				index++
				if(index > 3000)
					break
				// Del - Channel - Sender - Message
				// X   - #ss13   - bigdik - hi asl
				dat += "
X	[msg.channel]	[msg.sender]	[msg.message]
"
			dat += "
"

	message = defaultmsg
	//user << browse(dat, "window=message;size=700x700")
	//onclose(user, "message")
	var/datum/browser/popup = new(user, "hologram_console", name, 700, 700)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user as mob)
	if(isnull(linkedServer))
		user << "Could not complete brute-force: Linked Server Disconnected!"
	else
		var/currentKey = src.linkedServer.decryptkey
		user << "Brute-force completed! The key is '[currentKey]'."
	src.hacking = 0
	src.icon_state = normal_icon
	src.screen = 0 // Return the screen back to normal

/obj/machinery/computer/message_monitor/proc/UnmagConsole()
	src.icon_state = normal_icon
	src.emag = 0

/obj/machinery/computer/message_monitor/proc/ResetMessage()
	customsender 	= "System Administrator"
	customrecepient = null
	custommessage 	= "This is a test, please ignore."
	customjob 		= "Admin"

/obj/machinery/computer/message_monitor/Topic(href, href_list)
	if(..())
		return

	if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
		//Authenticate
		if (href_list["auth"])
			if(auth)
				auth = 0
				screen = 0
			else
				var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
				if(dkey && dkey != "")
					if(src.linkedServer.decryptkey == dkey)
						auth = 1
					else
						message = incorrectkey

		//Turn the server on/off.
		if (href_list["active"])
			if(auth)
				if(!linkedServer)
					return
				linkedServer.active = !linkedServer.active
		//Find a server
		if (href_list["find"])
			if(message_servers && message_servers.len > 1)
				src.linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers
				message = "NOTICE: Server selected."
			else if(message_servers && message_servers.len > 0)
				linkedServer = message_servers[1]
				message =  "NOTICE: Only Single Server Detected - Server selected."
			else
				message = noserver

		//View the logs - KEY REQUIRED
		if (href_list["view"])
			if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					src.screen = 1

		//Clears the logs - KEY REQUIRED
		if (href_list["clear"])
			if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					src.linkedServer.pda_msgs = list()
					message = "NOTICE: Logs cleared."
		//Clears the request console logs - KEY REQUIRED
		if (href_list["clearr"])
			if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					src.linkedServer.rc_msgs = list()
					message = "NOTICE: Logs cleared."
		//Clears the chatroom logs - KEY REQUIRED
		if (href_list["clearc"])
			if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					src.linkedServer.chat_msgs = list()
					message = "NOTICE: Logs cleared."
		//Change the password - KEY REQUIRED
		if (href_list["pass"])
			if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
					if(dkey && dkey != "")
						if(src.linkedServer.decryptkey == dkey)
							var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
							if(length(newkey) <= 3)
								message = "NOTICE: Decryption key too short!"
							else if(length(newkey) > 16)
								message = "NOTICE: Decryption key too long!"
							else if(newkey && newkey != "")
								src.linkedServer.decryptkey = newkey
							message = "NOTICE: Decryption key set."
						else
							message = incorrectkey

		//Hack the Console to get the password
		if (href_list["hack"])
			if(issilicon(usr) && is_special_character(usr))
				src.hacking = 1
				src.screen = 2
				src.icon_state = hack_icon
				//Time it takes to bruteforce is dependant on the password length.
				spawn(100*length(src.linkedServer.decryptkey))
					if(src && src.linkedServer && usr)
						BruteForce(usr)
		//Delete the log.
		if (href_list["delete"])
			//Are they on the view logs screen?
			if(screen == 1)
				if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
					message = noserver
				else //if(istype(href_list["delete"], /datum/data_pda_msg))
					src.linkedServer.pda_msgs -= locate(href_list["delete"])
					message = "NOTICE: Log Deleted!"
		//Delete the request console log.
		if (href_list["deleter"])
			//Are they on the view logs screen?
			if(screen == 4)
				if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
					message = noserver
				else //if(istype(href_list["delete"], /datum/data_pda_msg))
					src.linkedServer.rc_msgs -= locate(href_list["deleter"])
					message = "NOTICE: Log Deleted!"
		//Create a custom message
		if (href_list["msg"])
			if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					src.screen = 3
		//Fake messaging selection - KEY REQUIRED
		if (href_list["select"])
			if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
				screen = 0
			else
				switch(href_list["select"])

					//Reset
					if("Reset")
						ResetMessage()

					//Select Your Name
					if("Sender")
						customsender 	= stripped_input(usr, "Please enter the sender's name.")

					//Select Receiver
					if("Recepient")
						//Get out list of viable PDAs
						var/list/obj/item/device/pda/sendPDAs = get_viewable_pdas()
						if(PDAs && PDAs.len > 0)
							customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortNames(sendPDAs)
						else
							customrecepient = null

					//Enter custom job
					if("RecJob")
						customjob	 	= stripped_input(usr, "Please enter the sender's job.")

					//Enter message
					if("Message")
						custommessage	= stripped_input(usr, "Please enter your message.")

					//Send message
					if("Send")

						if(isnull(customsender) || customsender == "")
							customsender = "UNKNOWN"

						if(isnull(customrecepient))
							message = "NOTICE: No recepient selected!"
							return src.attack_hand(usr)

						if(isnull(custommessage) || custommessage == "")
							message = "NOTICE: No message entered!"
							return src.attack_hand(usr)

						var/obj/item/device/pda/PDARec = null
						for (var/obj/item/device/pda/P in get_viewable_pdas())
							if(P.owner == customsender)
								PDARec = P
						//Sender isn't faking as someone who exists
						if(isnull(PDARec))
							src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
							customrecepient.tnote += "← From [customsender] ([customjob]):
[custommessage]
"
							if (!customrecepient.silent)
								playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
								customrecepient.audible_message("\icon[customrecepient] *[customrecepient.ttone]*", null, 3)
								if( customrecepient.loc && ishuman(customrecepient.loc) )
									var/mob/living/carbon/human/H = customrecepient.loc
									H << "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)"
								log_pda("[usr]/([usr.ckey]) (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]")
								customrecepient.overlays.Cut()
								customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r")
						//Sender is faking as someone who exists
						else
							src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
							customrecepient.tnote += "← From [PDARec.owner] ([customjob]):
[custommessage]
"
							if (!customrecepient.silent)
								playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
								customrecepient.audible_message("\icon[customrecepient] *[customrecepient.ttone]*", null, 3)
								if( customrecepient.loc && ishuman(customrecepient.loc) )
									var/mob/living/carbon/human/H = customrecepient.loc
									H << "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)"
								log_pda("[usr]/([usr.ckey]) (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]")
								customrecepient.overlays.Cut()
								customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r")
						//Finally..
						ResetMessage()

		//Request Console Logs - KEY REQUIRED
		if(href_list["viewr"])
			if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					src.screen = 4
		//Chatroom Logs - KEY REQUIRED
		if(href_list["viewc"])
			if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
				message = noserver
			else
				if(auth)
					src.screen = 5

			//usr << href_list["select"]

		if (href_list["back"])
			src.screen = 0

	return src.attack_hand(usr)

/obj/item/weapon/paper/monitorkey
	//..()
	name = "monitor decryption key"
	var/obj/machinery/message_server/server = null

/obj/item/weapon/paper/monitorkey/New()
	..()
	spawn(10)
		if(message_servers)
			for(var/obj/machinery/message_server/server in message_servers)
				if(!isnull(server))
					if(!isnull(server.decryptkey))
						info = "
Daily Key Reset

The new message monitor key is '[server.decryptkey]'.
Please keep this a secret and away from the clown.
If necessary, change the password to a more secure one."
						info_links = info
						overlays += "paper_words"
						break


code:
/obj/machinery/computer/pod
	name = "mass driver launch control"
	desc = "A combined blastdoor and mass driver control unit."
	icon_state = "computer_generic"
	var/obj/machinery/mass_driver/connected = null
	var/title = "Mass Driver Controls"
	var/id = 1
	var/timing = 0
	var/time = 30
	var/range = 4

/obj/machinery/computer/pod/initialize()
	for(var/obj/machinery/mass_driver/M in range(range, src))
		if(M.id == id)
			connected = M
	..()

/obj/machinery/computer/pod/proc/alarm()
	if(stat & (NOPOWER|BROKEN))
		return

	if(!connected)
		viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!"
		return

	for(var/obj/machinery/door/poddoor/M in range(range, src))
		if(M.id == id)
			M.open()

	sleep(20)
	for(var/obj/machinery/mass_driver/M in range(range, src))
		if(M.id == id)
			M.power = connected.power
			M.drive()

	sleep(50)
	for(var/obj/machinery/door/poddoor/M in range(range, src))
		if(M.id == id)
			M.close()

/obj/machinery/computer/pod/attack_hand(mob/user)
	if(..())
		return

	var/dat = ""
	user.set_machine(src)
	if(connected)
		var/d2
		if(timing)	//door controls do not need timers.
			d2 = "Stop Time Launch"
		else
			d2 = "Initiate Time Launch"
		var/second = time % 60
		var/minute = (time - second) / 60
		dat += "
\nTimer System: [d2]\nTime Left: [minute ? "[minute]:" : null][second] - - + +"
		var/temp = ""
		var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 )
		for(var/t in L)
			if(t == connected.power)
				temp += "[t] "
			else
				temp += "[t] "
		dat += "
\nPower Level: [temp]
\nFiring Sequence
\nTest Fire Driver
\nToggle Outer Door
"
	else
		dat += "
\nToggle Outer Door
"
	dat += "

Close"
	add_fingerprint(usr)
	var/datum/browser/popup = new(user, "computer", title, 400, 500)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
	popup.open()

/obj/machinery/computer/pod/process()
	if(!..())
		return
	if(timing)
		if(time > 0)
			time = round(time) - 1
		else
			alarm()
			time = 0
			timing = 0
		updateDialog()

/obj/machinery/computer/pod/Topic(href, href_list)
	if(..())
		return
	if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
		usr.set_machine(src)
		if(href_list["power"])
			var/t = text2num(href_list["power"])
			t = min(max(0.25, t), 16)
			if(connected)
				connected.power = t
		if(href_list["alarm"])
			alarm()
		if(href_list["time"])
			timing = text2num(href_list["time"])
		if(href_list["tp"])
			var/tp = text2num(href_list["tp"])
			time += tp
			time = min(max(round(time), 0), 120)
		if(href_list["door"])
			for(var/obj/machinery/door/poddoor/M in range(range, src))
				if(M.id == id)
					if(M.density)
						M.open()
					else
						M.close()
		if(href_list["drive"])
			for(var/obj/machinery/mass_driver/M in range(range, src))
				if(M.id == id)
					M.power = connected.power
					M.drive()
		updateUsrDialog()

/obj/machinery/computer/pod/old
	icon_state = "old"
	name = "\improper DoorMex control console"
	title = "Door Controls"

/obj/machinery/computer/pod/old/syndicate
	name = "\improper ProComp Executive IIc"
	desc = "The Syndicate operate on a tight budget. Operates external airlocks."
	title = "External Airlock Controls"
	req_access = list(access_syndicate)

/obj/machinery/computer/pod/old/syndicate/attack_hand(mob/user)
	if(!allowed(user))
		user << "Access denied."
		return
	else
		..()

/obj/machinery/computer/pod/old/swf
	name = "\improper Magix System IV"
	desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorceror's Edition"


code:
// the power monitoring computer
// for the moment, just report the status of all APCs in the same powernet
/obj/machinery/computer/monitor
	name = "power monitoring console"
	desc = "It monitors power levels across the station."
	icon = 'icons/obj/computer.dmi'
	icon_state = "power"
	density = 1
	anchored = 1
	use_power = 2
	idle_power_usage = 20
	active_power_usage = 80
	circuit = /obj/item/weapon/circuitboard/powermonitor
	var/datum/powernet/powernet = null

//fix for issue 521, by QualityVan.
//someone should really look into why circuits have a powernet var, it's several kinds of retarded.
/obj/machinery/computer/monitor/New()
	..()
	var/obj/structure/cable/attached = null
	var/turf/T = loc
	if(isturf(T))
		attached = locate() in T
	if(attached)
		powernet = attached.get_powernet()

/obj/machinery/computer/monitor/process() //oh shit, somehow we didnt end up with a powernet... lets look for one.
	if(!powernet)
		var/obj/structure/cable/attached = null
		var/turf/T = loc
		if(isturf(T))
			attached = locate() in T
		if(attached)
			powernet = attached.get_powernet()
	return

/obj/machinery/computer/monitor/attack_hand(mob/user)
	if(..())
		return
	interact(user)

/obj/machinery/computer/monitor/interact(mob/user)
	if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
		if (!istype(user, /mob/living/silicon))
			user.unset_machine()
			user << browse(null, "window=powcomp")
			return

	user.set_machine(src)
	var/t = ""

	t += "Refresh Close

"

	if(!powernet)
		t += "No connection."
	else

		var/list/L = list()
		for(var/obj/machinery/power/terminal/term in powernet.nodes)
			if(istype(term.master, /obj/machinery/power/apc))
				var/obj/machinery/power/apc/A = term.master
				L += A

		t += "
Total power: [powernet.avail] W
Total load:  [num2text(powernet.viewload,10)] W
"

		t += ""

		if(L.len > 0)

			t += "Area                           Eqp./Lgt./Env.  Load   Cell
"

			var/list/S = list(" Off","AOff","  On", " AOn")
			var/list/chg = list("N","C","F")

			for(var/obj/machinery/power/apc/A in L)

				t += copytext(add_tspace("\The [A.area]", 30), 1, 30)
				t += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(A.lastused_total, 6)]  [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : "  N/C"]
"

		t += "
"

	//user << browse(t, "window=powcomp;size=420x900")
	//onclose(user, "powcomp")
	var/datum/browser/popup = new(user, "powcomp", name, 420, 450)
	popup.set_content(t)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()

/obj/machinery/computer/monitor/Topic(href, href_list)
	if(..())
		return
	if( href_list["close"] )
		usr << browse(null, "window=powcomp")
		usr.unset_machine()
		return
	if( href_list["update"] )
		src.updateDialog()
		return


code:
/obj/machinery/computer/prisoner
	name = "prisoner management console"
	desc = "Used to manage tracking implants placed inside criminals."
	icon = 'icons/obj/computer.dmi'
	icon_state = "explosive"
	req_access = list(access_brig)
	circuit = "/obj/item/weapon/circuitboard/prisoner"
	var/id = 0.0
	var/temp = null
	var/status = 0
	var/timeleft = 60
	var/stop = 0.0
	var/screen = 0 // 0 - No Access Denied, 1 - Access allowed
	var/obj/item/weapon/card/id/prisoner/inserted_id
	circuit = /obj/item/weapon/circuitboard/prisoner

/obj/machinery/computer/prisoner/attack_hand(var/mob/user as mob)
	if(..())
		return
	user.set_machine(src)
	var/dat = ""
	if(screen == 0)
		dat += "
Unlock Console"
	else if(screen == 1)
		dat += "
Prisoner ID Management
"
		if(istype(inserted_id))
			dat += text("[inserted_id]
")
			dat += text("Collected Points: [inserted_id.points]. Reset.
")
			dat += text("Card goal: [inserted_id.goal].  Set
")
			dat += text("Space Law recommends quotas of 100 points per minute they would normally serve in the brig.
")
		else
			dat += text("Insert Prisoner ID.
")
		dat += "
Prisoner Implant Management
"
		dat += "
Chemical Implants
"
		var/turf/Tr = null
		for(var/obj/item/weapon/implant/chem/C in world)
			Tr = get_turf(C)
			if((Tr) && (Tr.z != src.z))	continue//Out of range
			if(!C.implanted) continue
			dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: "
			dat += "((1))"
			dat += "((5))"
			dat += "((10))
"
			dat += "********************************
"
		dat += "
Tracking Implants
"
		for(var/obj/item/weapon/implant/tracking/T in world)
			if(!iscarbon(T.imp_in))
				continue
			if(!T.implanted)
				continue
			Tr = get_turf(T)
			if((Tr) && (Tr.z != src.z))
				continue//Out of range

			var/loc_display = "Unknown"
			var/mob/living/carbon/M = T.imp_in
			if(Tr.z == ZLEVEL_STATION && !istype(M.loc, /turf/space))
				var/turf/mob_loc = get_turf(M)
				loc_display = mob_loc.loc

			dat += "ID: [T.id] | Location: [loc_display]
"
			dat += "(Message Holder) |
"
			dat += "********************************
"
		dat += "
Lock Console"

	//user << browse(dat, "window=computer;size=400x500")
	//onclose(user, "computer")
	var/datum/browser/popup = new(user, "computer", "Prisoner Management Console", 400, 500)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

/obj/machinery/computer/prisoner/attackby(obj/item/I as obj, mob/user as mob, params)
	if(istype(I, /obj/item/weapon/card/id))
		return attack_hand(user)
	..()

/obj/machinery/computer/prisoner/process()
	if(!..())
		src.updateDialog()
	return

/obj/machinery/computer/prisoner/Topic(href, href_list)
	if(..())
		return
	if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
		usr.set_machine(src)

		if(href_list["id"])
			if(href_list["id"] =="insert" && !istype(inserted_id))
				var/obj/item/weapon/card/id/prisoner/I = usr.get_active_hand()
				if(istype(I))
					usr.drop_item()
					I.loc = src
					inserted_id = I
				else usr << "No valid ID."
			else if(istype(inserted_id))
				switch(href_list["id"])
					if("eject")
						inserted_id.loc = get_turf(src)
						inserted_id.verb_pickup()
						inserted_id = null
					if("reset")
						inserted_id.points = 0
					if("setgoal")
						var/num = round(input(usr, "Choose prisoner's goal:", "Input an Integer", null) as num|null)
						if(num >= 0)
							num = min(num,1000) //Cap the quota to the equivilent of 10 minutes.
							inserted_id.goal = num
		else if(href_list["inject1"])
			var/obj/item/weapon/implant/I = locate(href_list["inject1"])
			if(I)	I.activate(1)
		else if(href_list["inject5"])
			var/obj/item/weapon/implant/I = locate(href_list["inject5"])
			if(I)	I.activate(5)

		else if(href_list["inject10"])
			var/obj/item/weapon/implant/I = locate(href_list["inject10"])
			if(I)	I.activate(10)

		else if(href_list["lock"])
			if(src.allowed(usr))
				screen = !screen
			else
				usr << "Unauthorized Access."

		else if(href_list["warn"])
			var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN)
			if(!warning) return
			var/obj/item/weapon/implant/I = locate(href_list["warn"])
			if((I)&&(I.imp_in))
				var/mob/living/carbon/R = I.imp_in
				R << "You hear a voice in your head saying: '[warning]'"
				log_say("[usr]/[usr.ckey] sent an implant message to [R]/[R.ckey]: '[warning]'")

		src.add_fingerprint(usr)
	src.updateUsrDialog()
	return


code:
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31

/obj/machinery/computer/robotics
	name = "robotics control console"
	desc = "Used to remotely lockdown or detonate linked Cyborgs."
	icon = 'icons/obj/computer.dmi'
	icon_state = "robot"
	req_access = list(access_robotics)
	circuit = /obj/item/weapon/circuitboard/robotics
	var/temp = null

/obj/machinery/computer/robotics/proc/can_control(var/mob/user, var/mob/living/silicon/robot/R)
	if(!istype(R))
		return 0
	if(istype(user, /mob/living/silicon/ai))
		if (R.connected_ai != user)
			return 0
	if(istype(user, /mob/living/silicon/robot))
		if (R != user)
			return 0
	if(R.scrambledcodes)
		return 0
	return 1

/obj/machinery/computer/robotics/attack_hand(var/mob/user as mob)
	if(..())
		return
	interact(user)

/obj/machinery/computer/robotics/interact(var/mob/user as mob)
	if (ismommi(user))
		user << "You cannot interface with this machine."
		return
	if (src.z > 6)
		user << "Unable to establish a connection: \black You're too far away from the station!"
		return
	user.set_machine(src)
	var/dat
	var/robots = 0
	for(var/mob/living/silicon/robot/R in mob_list)
		if(!can_control(user, R))
			continue
		robots++
		dat += "[R.name] |"
		if(R.stat)
			dat += " Not Responding |"
		else if (!R.canmove)
			dat += " Locked Down |"
		else
			dat += " Operating Normally |"
		if (!R.canmove)
		else if(R.cell)
			dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
		else
			dat += " No Cell Installed |"
		if(R.module)
			dat += " Module Installed ([R.module.name]) |"
		else
			dat += " No Module Installed |"
		if(R.connected_ai)
			dat += " Slaved to [R.connected_ai.name] |"
		else
			dat += " Independent from AI |"
		if (istype(user, /mob/living/silicon))
			if(issilicon(user) && is_special_character(user) && !R.emagged)
				dat += "(Hack) "
		dat += "([R.canmove ? "Lockdown" : "Release"]) "
		dat += "(Destroy)"
		dat += "
"

	if(!robots)
		dat += "No Cyborg Units detected within access parameters."

	var/datum/browser/popup = new(user, "computer", "Cyborg Control Console", 400, 500)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

/obj/machinery/computer/robotics/Topic(href, href_list)
	if(..())
		return

	if (href_list["temp"])
		src.temp = null

	else if (href_list["killbot"])
		if(src.allowed(usr))
			var/mob/living/silicon/robot/R = locate(href_list["killbot"])
			if(can_control(usr, R))
				var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
				if(choice == "Confirm" && can_control(usr, R) && !..())
					if(R.mind && R.mind.special_role && R.emagged)
						R << "Extreme danger.  Termination codes detected.  Scrambling security codes and automatic AI unlink triggered."
						R.ResetSecurityCodes()
					else
						message_admins("[key_name(usr, usr.client)](JMP) detonated [key_name(R, R.client)](JMP)!")
						log_game("\[key_name(usr)] detonated [key_name(R)]!")
						if(R.connected_ai)
							R.connected_ai << "

ALERT - Cyborg detonation detected: [R.name]
"
						R.self_destruct()
		else
			usr << "Access Denied."

	else if (href_list["stopbot"])
		if(src.allowed(usr))
			var/mob/living/silicon/robot/R = locate(href_list["stopbot"])
			if(can_control(usr, R))
				var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
				if(choice == "Confirm" && can_control(usr, R) && !..())
					message_admins("[key_name(usr, usr.client)](JMP) [R.canmove ? "locked down" : "released"] [key_name(R, R.client)](JMP)!")
					log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!")
					R.SetLockdown(!R.lockcharge)
					R << "[!R.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]"
					if(R.connected_ai)
						R.connected_ai << "[!R.lockcharge ? "NOTICE - Cyborg lockdown lifted" : "ALERT - Cyborg lockdown detected"]: [R.name]
"

		else
			usr << "Access Denied."

	else if (href_list["magbot"])
		if(issilicon(usr) && is_special_character(usr))
			var/mob/living/silicon/robot/R = locate(href_list["magbot"])
			if(istype(R) && !R.emagged && R.connected_ai == usr && !R.scrambledcodes && can_control(usr, R))
				log_game("[key_name(usr)] emagged [R.name] using robotic console!")
				R.SetEmagged(1)
				if(R.mind.special_role)
					R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes

	src.updateUsrDialog()
	return