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_screen = "medcomp"
	icon_keyboard = "med_key"
	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, mob/user, params)
	if(istype(O, /obj/item/weapon/card/id) && !scan)
		if(!user.drop_item())
			return
		O.loc = src
		scan = O
		user << "You insert [O]."
	else
		..()

/obj/machinery/computer/med_data/attack_hand(mob/user)
	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)
					dat += {"
Search Records

List Records

Virus Database

Medbot Tracking

Record Maintenance

{Log Out}

"}
				if(2)
					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)
					dat += text("Records Maintenance
\nBackup To Disk
\nUpload From Disk
\nDelete All Records
\n
\nBack", src, src, src, src)
				if(4)

					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)
					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)
					dat += "Medical Robot Monitor"
					dat += "Back"
					dat += "
Medical Robots:"
					var/bdat = null
					for(var/mob/living/simple_animal/bot/medbot/M in living_mob_list)
						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)) || IsAdminGhost(usr))
		usr.set_machine(src)
		if(href_list["temp"])
			src.temp = null
		if(href_list["scan"])
			if(src.scan)
				if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand())
					usr.put_in_hands(scan)
				else
					scan.loc = get_turf(src)
				src.scan = null
			else
				var/obj/item/I = usr.get_active_hand()
				if(istype(I, /obj/item/weapon/card/id))
					if(!usr.drop_item())
						return
					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(IsAdminGhost(usr))
				src.active1 = null
				src.active2 = null
				src.authenticated = 1
				src.rank = "Central Command"
				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 = stripped_input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null)
							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)
					if(prob(10))
						R.fields["name"] = random_unique_lizard_name(R.fields["sex"],1)
					else
						R.fields["name"] = random_unique_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))
			qdel(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 = "laptop"
	icon_screen = "medlaptop"
	icon_keyboard = "laptop_key"


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_screen = "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_system/spark_spread/spark_system = new /datum/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/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, mob/living/user, params)
	if(istype(O, /obj/item/weapon/screwdriver) && emagged)
		//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
	..()

/obj/machinery/computer/message_monitor/emag_act(mob/user)
	if(!emagged)
		if(!isnull(src.linkedServer))
			emagged = 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/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(mob/living/user)
	if(..())
		return
	//If the computer is being hacked or is emagged, display the reboot message.
	if(hacking || emagged)
		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 || emagged)
		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]. Clear Message Logs

"
					dat += "
	[++i]. Clear Request Console 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][pda.photo ? "(Photo)":""]
"
			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 += "
"

	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)
	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.screen = 0 // Return the screen back to normal

/obj/machinery/computer/message_monitor/proc/UnmagConsole()
	src.emagged = 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(!linkedServer || linkedServer.stat & (NOPOWER|BROKEN))
				message = noserver
			else
				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) 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."
		//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
				//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

		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

license: mit


code:
/obj/machinery/computer/pod
	name = "mass driver launch control"
	desc = "A combined blastdoor and mass driver control unit."
	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
	name = "\improper DoorMex control console"
	title = "Door Controls"
	icon_state = "oldcomp"
	icon_screen = "library"
	icon_keyboard = null

/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:
/obj/machinery/computer/prisoner
	name = "prisoner management console"
	desc = "Used to manage tracking implants placed inside criminals."
	icon_screen = "explosive"
	icon_keyboard = "security_key"
	req_access = list(access_brig)
	circuit = "/obj/item/weapon/circuitboard/prisoner"
	var/id = 0
	var/temp = null
	var/status = 0
	var/timeleft = 60
	var/stop = 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(mob/user)
	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 tracked_implants)
			Tr = get_turf(C)
			if((Tr) && (Tr.z != src.z))
				continue//Out of range
			if(!C.implanted)
				continue
			dat += "ID: [C.imp_in.name] | Remaining Units: [C.reagents.total_volume]
"
			dat += "| Inject: "
			dat += "((1))"
			dat += "((5))"
			dat += "((10))
"
			dat += "********************************
"
		dat += "
Tracking Implants
"
		for(var/obj/item/weapon/implant/tracking/T in tracked_implants)
			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/open/space))
				var/turf/mob_loc = get_turf(M)
				loc_display = mob_loc.loc

			dat += "ID: [T.imp_in.name] | 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, mob/user, 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))
					if(!usr.drop_item())
						return
					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_screen = "robot"
	icon_keyboard = "rd_key"
	req_access = list(access_robotics)
	circuit = /obj/item/weapon/circuitboard/robotics
	var/temp = null

/obj/machinery/computer/robotics/proc/can_control(mob/user, 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(mob/user)
	if(..())
		return
	interact(user)

/obj/machinery/computer/robotics/interact(mob/user)
	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) || IsAdminGhost(usr))
			if(((issilicon(user) && is_special_character(user)) || IsAdminGhost(usr)) && !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_admin(usr)] (FLW) 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_admin(usr)] (FLW) [R.canmove ? "locked down" : "released"] [key_name(R, R.client)](FLW)!")
					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)) || IsAdminGhost(usr))
			var/mob/living/silicon/robot/R = locate(href_list["magbot"])
			if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(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


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

/obj/machinery/computer/secure_data//TODO:SANITY
	name = "security records console"
	desc = "Used to view and edit personnel's security records"
	icon_screen = "security"
	icon_keyboard = "security_key"
	req_one_access = list(access_security, access_forensics_lockers)
	circuit = /obj/item/weapon/circuitboard/secure_data
	var/obj/item/weapon/card/id/scan = null
	var/authenticated = null
	var/rank = null
	var/screen = null
	var/datum/data/record/active1 = null
	var/datum/data/record/active2 = null
	var/a_id = null
	var/temp = null
	var/printing = null
	var/can_change_id = 0
	var/list/Perp
	var/tempname = null
	//Sorting Variables
	var/sortBy = "name"
	var/order = 1 // -1 = Descending - 1 = Ascending

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

//Someone needs to break down the dat += into chunks instead of long ass lines.
/obj/machinery/computer/secure_data/attack_hand(mob/user)
	if(..())
		return
	if(src.z > 6)
		user << "Unable to establish a connection: \black You're too far away from the station!"
		return
	var/dat

	if(temp)
		dat = text("<TT>[]</TT>

Clear Screen", temp, src)
	else
		dat = text("Confirm Identity: []
", src, (scan ? text("[]", scan.name) : "----------"))
		if(authenticated)
			switch(screen)
				if(1)

					//body tag start + onload and onkeypress (onkeyup) javascript event calls
					dat += ""
					//search bar javascript
					dat += {"

	"}
					dat += {"

"}
					dat += text("New Record
", src)
					//search bar
					dat += {"

									Search: <input type='text' id='filter' value='' style='width:300px;'>

					"}
					dat += {"

Records:

Name
ID
Rank
Fingerprints
Criminal Status

"}
					if(!isnull(data_core.general))
						for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order))
							var/crimstat = ""
							for(var/datum/data/record/E in data_core.security)
								if((E.fields["name"] == R.fields["name"]) && (E.fields["id"] == R.fields["id"]))
									crimstat = E.fields["criminal"]
							var/background
							switch(crimstat)
								if("*Arrest*")
									background = "'background-color:#990000;'"
								if("Incarcerated")
									background = "'background-color:#CD6500;'"
								if("Parolled")
									background = "'background-color:#CD6500;'"
								if("Discharged")
									background = "'background-color:#006699;'"
								if("None")
									background = "'background-color:#4F7529;'"
								if("")
									background = "''" //"'background-color:#FFFFFF;'"
									crimstat = "No Record."
							dat += "
"
							dat += text("<input type='hidden' value='[] [] [] []'></input>[]	", R.fields["name"], R.fields["id"], R.fields["rank"], R.fields["fingerprint"], src, R, R.fields["name"])
							dat += text("[]	", R.fields["id"])
							dat += text("[]	", R.fields["rank"])
							dat += text("[]	", R.fields["fingerprint"])
							dat += text("[]
", crimstat)
						dat += {"

"}
					dat += text("Record Maintenance

", src)
					dat += text("{Log Out}",src)
				if(2)
					dat += "Records Maintenance
"
					dat += "
Delete All Records

Back"
				if(3)
					dat += "Security Record
"
					if(istype(active1, /datum/data/record) && data_core.general.Find(active1))
						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"]]

ID:	 [active1.fields["id"]]

Sex:	 [active1.fields["sex"]]

Age:	 [active1.fields["age"]]
"}
						if(config.mutant_races)
							dat += "
Species:	 [active1.fields["species"]]
"
						dat += {"
Rank:	 [active1.fields["rank"]]

Fingerprint:	 [active1.fields["fingerprint"]]

Physical Status:	 [active1.fields["p_stat"]]

Mental Status:	 [active1.fields["m_stat"]]

						Update front photo

						Update side photo

"}
					else
						dat += "
General Record Lost!
"
					if((istype(active2, /datum/data/record) && data_core.security.Find(active2)))
						dat += "Security Data"
						dat += "
Criminal Status: [active2.fields["criminal"]]"
						dat += "

Minor Crimes: Add New"

						dat +={"

						Crime
						Details
						Author
						Time Added
						Del

"}
						for(var/datum/data/crime/c in active2.fields["mi_crim"])
							dat += "
[c.crimeName]	"
							dat += "[c.crimeDetails]	"
							dat += "[c.author]	"
							dat += "[c.time]	"
							dat += "\[X\]	"
							dat += "
"
						dat += "
"

						dat += "
Major Crimes: Add New"

						dat +={"

						Crime
						Details
						Author
						Time Added
						Del

"}
						for(var/datum/data/crime/c in active2.fields["ma_crim"])
							dat += "
[c.crimeName]	"
							dat += "[c.crimeDetails]	"
							dat += "[c.author]	"
							dat += "[c.time]	"
							dat += "\[X\]	"
							dat += "
"
						dat += "
"

						dat += "
\nImportant Notes:
\n\t [active2.fields["notes"]] "
						dat += "

Comments/Log
"
						var/counter = 1
						while(active2.fields[text("com_[]", counter)])
							dat += (active2.fields[text("com_[]", counter)] + "
")
							if(active2.fields[text("com_[]", counter)] != "Deleted")
								dat += text("Delete Entry

", src, counter)
							counter++
						dat += text("Add Entry

", src)
						dat += text("Delete Record (Security Only)
", src)
					else
						dat += "Security Record Lost!
"
						dat += text("New Security Record

", src)
					dat += text("Delete Record (ALL)
Print Record
\nBack
", src, src, src)
				else
		else
			dat += text("{Log In}", src)
	//user << browse(text("<TITLE>Security Records</TITLE><TT>[]</TT>", dat), "window=secure_rec;size=600x400")
	//onclose(user, "secure_rec")
	var/datum/browser/popup = new(user, "secure_rec", "Security Records Console", 600, 400)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

/*Revised /N
I can't be bothered to look more of the actual code outside of switch but that probably needs revising too.
What a mess.*/
/obj/machinery/computer/secure_data/Topic(href, href_list)
	. = ..()
	if(.)
		return .
	if(!( data_core.general.Find(active1) ))
		active1 = null
	if(!( data_core.security.Find(active2) ))
		active2 = null
	if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)) || IsAdminGhost(usr))
		usr.set_machine(src)
		switch(href_list["choice"])
// SORTING!
			if("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)
//BASIC FUNCTIONS
			if("Clear Screen")
				temp = null

			if("Return")
				screen = 1
				active1 = null
				active2 = null

			if("Confirm Identity")
				if(scan)
					if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand())
						usr.put_in_hands(scan)
					else
						scan.loc = get_turf(src)
					scan = null
				else
					var/obj/item/I = usr.get_active_hand()
					if(istype(I, /obj/item/weapon/card/id))
						if(!usr.drop_item())
							return
						I.loc = src
						scan = I

			if("Log Out")
				authenticated = null
				screen = null
				active1 = null
				active2 = null

			if("Log In")
				if(istype(usr, /mob/living/silicon))
					var/mob/living/silicon/borg = usr
					active1 = null
					active2 = null
					authenticated = borg.name
					rank = "AI"
					screen = 1
				else if(IsAdminGhost(usr))
					active1 = null
					active2 = null
					authenticated = usr.client.holder.admin_signature
					rank = "Central Command"
					screen = 1
				else if(istype(scan, /obj/item/weapon/card/id))
					active1 = null
					active2 = null
					if(check_access(scan))
						authenticated = scan.registered_name
						rank = scan.assignment
						screen = 1
//RECORD FUNCTIONS
			if("Record Maintenance")
				screen = 2
				active1 = null
				active2 = null

			if("Browse Record")
				var/datum/data/record/R = locate(href_list["d_rec"])
				var/S = locate(href_list["d_rec"])
				if(!( data_core.general.Find(R) ))
					temp = "Record Not Found!"
				else
					for(var/datum/data/record/E in data_core.security)
						if((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
							S = E
					active1 = R
					active2 = S
					screen = 3

			if("Print Record")
				if(!( printing ))
					printing = 1
					data_core.securityPrintCount++
					playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1)
					sleep(30)
					var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc )
					P.info = "Security Record - (SR-[data_core.securityPrintCount])
"
					if((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
						P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"])
						if(config.mutant_races)
							P.info += "\nSpecies: [active1.fields["species"]]
"
						P.info += text("\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"])
					else
						P.info += "General Record Lost!
"
					if((istype(active2, /datum/data/record) && data_core.security.Find(active2)))
						P.info += text("
\nSecurity Data
\nCriminal Status: []", active2.fields["criminal"])

						P.info += "
\n
\nMinor Crimes:
\n"
						P.info +={"

Crime
Details
Author
Time Added

"}
						for(var/datum/data/crime/c in active2.fields["mi_crim"])
							P.info += "
[c.crimeName]	"
							P.info += "[c.crimeDetails]	"
							P.info += "[c.author]	"
							P.info += "[c.time]	"
							P.info += "
"
						P.info += "
"

						P.info += "
\nMajor Crimes:
\n"
						P.info +={"

Crime
Details
Author
Time Added

"}
						for(var/datum/data/crime/c in active2.fields["ma_crim"])
							P.info += "
[c.crimeName]	"
							P.info += "[c.crimeDetails]	"
							P.info += "[c.author]	"
							P.info += "[c.time]	"
							P.info += "
"
						P.info += "
"

						P.info += text("
\nImportant Notes:
\n\t[]
\n
\nComments/Log
", active2.fields["notes"])
						var/counter = 1
						while(active2.fields[text("com_[]", counter)])
							P.info += text("[]
", active2.fields[text("com_[]", counter)])
							counter++
						P.name = text("SR-[] '[]'", data_core.securityPrintCount, active1.fields["name"])
					else
						P.info += "Security Record Lost!
"
						P.name = text("SR-[] '[]'", data_core.securityPrintCount, "Record Lost")
					P.info += "</TT>"
					printing = null
//RECORD DELETE
			if("Delete All Records")
				temp = ""
				temp += "Are you sure you wish to delete all Security records?
"
				temp += "Yes
"
				temp += "No"

			if("Purge All Records")
				investigate_log("[usr.name] ([usr.key]) has purged all the security records.", "records")
				for(var/datum/data/record/R in data_core.security)
					qdel(R)
				data_core.security.Cut()
				temp = "All Security records deleted."

			if("Add Entry")
				if(!( istype(active2, /datum/data/record) ))
					return
				var/a2 = active2
				var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null)
				if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
					return
				var/counter = 1
				while(active2.fields[text("com_[]", counter)])
					counter++
				active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
[]", src.authenticated, src.rank, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1,)

			if("Delete Record (ALL)")
				if(active1)
					temp = "
Are you sure you wish to delete the record (ALL)?
"
					temp += "Yes
"
					temp += "No"

			if("Delete Record (Security)")
				if(active2)
					temp = "
Are you sure you wish to delete the record (Security Portion Only)?
"
					temp += "Yes
"
					temp += "No"

			if("Delete Entry")
				if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
					active2.fields[text("com_[]", href_list["del_c"])] = "Deleted"
//RECORD CREATE
			if("New Record (Security)")
				if((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) )))
					var/datum/data/record/R = new /datum/data/record()
					R.fields["name"] = active1.fields["name"]
					R.fields["id"] = active1.fields["id"]
					R.name = text("Security Record #[]", R.fields["id"])
					R.fields["criminal"] = "None"
					R.fields["mi_crim"] = list()
					R.fields["ma_crim"] = list()
					R.fields["notes"] = "No notes."
					data_core.security += R
					active2 = R
					screen = 3

			if("New Record (General)")
				//General Record
				var/datum/data/record/G = new /datum/data/record()
				G.fields["name"] = "New Record"
				G.fields["id"] = "[num2hex(rand(1, 1.6777215E7), 6)]"
				G.fields["rank"] = "Unassigned"
				G.fields["sex"] = "Male"
				G.fields["age"] = "Unknown"
				if(config.mutant_races)
					G.fields["species"] = "Human"
				G.fields["photo_front"] = new /icon()
				G.fields["photo_side"] = new /icon()
				G.fields["fingerprint"] = "?????"
				G.fields["p_stat"] = "Active"
				G.fields["m_stat"] = "Stable"
				data_core.general += G
				active1 = G

				//Security Record
				var/datum/data/record/R = new /datum/data/record()
				R.fields["name"] = active1.fields["name"]
				R.fields["id"] = active1.fields["id"]
				R.name = text("Security Record #[]", R.fields["id"])
				R.fields["criminal"] = "None"
				R.fields["mi_crim"] = list()
				R.fields["ma_crim"] = list()
				R.fields["notes"] = "No notes."
				data_core.security += R
				active2 = R

				//Medical Record
				var/datum/data/record/M = new /datum/data/record()
				M.fields["id"]			= active1.fields["id"]
				M.fields["name"]		= active1.fields["name"]
				M.fields["blood_type"]	= "?"
				M.fields["b_dna"]		= "?????"
				M.fields["mi_dis"]		= "None"
				M.fields["mi_dis_d"]	= "No minor disabilities have been declared."
				M.fields["ma_dis"]		= "None"
				M.fields["ma_dis_d"]	= "No major disabilities have been diagnosed."
				M.fields["alg"]			= "None"
				M.fields["alg_d"]		= "No allergies have been detected in this patient."
				M.fields["cdi"]			= "None"
				M.fields["cdi_d"]		= "No diseases have been diagnosed at the moment."
				M.fields["notes"]		= "No notes."
				data_core.medical += M

//FIELD FUNCTIONS
			if("Edit Field")
				var/a1 = active1
				var/a2 = active2

				switch(href_list["field"])
					if("name")
						if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record))
							var/t1 = copytext(sanitize(input("Please input name:", "Secure. records", active1.fields["name"], null)  as text),1,MAX_MESSAGE_LEN)
							if(!canUseSecurityRecordsConsole(usr, t1, a1))
								return
							if(istype(active1, /datum/data/record))
								active1.fields["name"] = t1
							if(istype(active2, /datum/data/record))
								active2.fields["name"] = t1
					if("id")
						if(istype(active2,/datum/data/record) || istype(active1,/datum/data/record))
							var/t1 = stripped_input(usr, "Please input id:", "Secure. records", active1.fields["id"], null)
							if(!canUseSecurityRecordsConsole(usr, t1, a1))
								return
							if(istype(active1,/datum/data/record))
								active1.fields["id"] = t1
							if(istype(active2,/datum/data/record))
								active2.fields["id"] = t1
					if("fingerprint")
						if(istype(active1, /datum/data/record))
							var/t1 = stripped_input(usr, "Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null)
							if(!canUseSecurityRecordsConsole(usr, t1, a1))
								return
							active1.fields["fingerprint"] = t1
					if("sex")
						if(istype(active1, /datum/data/record))
							if(active1.fields["sex"] == "Male")
								active1.fields["sex"] = "Female"
							else
								active1.fields["sex"] = "Male"
					if("age")
						if(istype(active1, /datum/data/record))
							var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
							if(!canUseSecurityRecordsConsole(usr, "age", a1))
								return
							active1.fields["age"] = t1
					if("species")
						if(istype(active1, /datum/data/record))
							var/t1 = input("Select a species", "Species Selection") as null|anything in roundstart_species
							if(!canUseSecurityRecordsConsole(usr, t1, a1))
								return
							active1.fields["species"] = t1
					if("show_photo_front")
						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("upd_photo_front")
						var/icon/photo = get_photo(usr)
						if(photo)
							qdel(active1.fields["photo_front"])
							active1.fields["photo_front"] = photo
					if("show_photo_side")
						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)
					if("upd_photo_side")
						var/icon/photo = get_photo(usr)
						if(photo)
							qdel(active1.fields["photo_side"])
							active1.fields["photo_side"] = photo
					if("mi_crim_add")
						if(istype(active1, /datum/data/record))
							var/t1 = stripped_input(usr, "Please input minor crime names:", "Secure. records", "", null)
							var/t2 = stripped_multiline_input(usr, "Please input minor crime details:", "Secure. records", "", null)
							if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
								return
							var/crime = data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
							data_core.addMinorCrime(active1.fields["id"], crime)
					if("mi_crim_delete")
						if(istype(active1, /datum/data/record))
							if(href_list["cdataid"])
								if(!canUseSecurityRecordsConsole(usr, "delete", null, a2))
									return
								data_core.removeMinorCrime(active1.fields["id"], href_list["cdataid"])
					if("ma_crim_add")
						if(istype(active1, /datum/data/record))
							var/t1 = stripped_input(usr, "Please input major crime names:", "Secure. records", "", null)
							var/t2 = stripped_multiline_input(usr, "Please input major crime details:", "Secure. records", "", null)
							if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
								return
							var/crime = data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
							data_core.addMajorCrime(active1.fields["id"], crime)
					if("ma_crim_delete")
						if(istype(active1, /datum/data/record))
							if(href_list["cdataid"])
								if(!canUseSecurityRecordsConsole(usr, "delete", null, a2))
									return
								data_core.removeMajorCrime(active1.fields["id"], href_list["cdataid"])
					if("notes")
						if(istype(active2, /datum/data/record))
							var/t1 = stripped_input(usr, "Please summarize notes:", "Secure. records", active2.fields["notes"], null)
							if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
								return
							active2.fields["notes"] = t1
					if("criminal")
						if(istype(active2, /datum/data/record))
							temp = "
Criminal Status:
"
							temp += "
"
							temp += "
None
"
							temp += "
*Arrest*
"
							temp += "
Incarcerated
"
							temp += "
Parolled
"
							temp += "
Discharged
"
							temp += "
"
					if("rank")
						var/list/L = list( "Head of Personnel", "Captain", "AI", "Central Command" )
						//This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
						if((istype(active1, /datum/data/record) && L.Find(rank)))
							temp = "
Rank:
"
							temp += "
"
							for(var/rank in get_all_jobs())
								temp += "
[rank]
"
							temp += "
"
						else
							alert(usr, "You do not have the required rank to do this!")
//TEMPORARY MENU FUNCTIONS
			else//To properly clear as per clear screen.
				temp=null
				switch(href_list["choice"])
					if("Change Rank")
						if(active1)
							active1.fields["rank"] = href_list["rank"]
							if(href_list["rank"] in get_all_jobs())
								active1.fields["real_rank"] = href_list["real_rank"]

					if("Change Criminal Status")
						if(active2)
							var/old_field = active2.fields["criminal"]
							switch(href_list["criminal2"])
								if("none")
									active2.fields["criminal"] = "None"
								if("arrest")
									active2.fields["criminal"] = "*Arrest*"
								if("incarcerated")
									active2.fields["criminal"] = "Incarcerated"
								if("parolled")
									active2.fields["criminal"] = "Parolled"
								if("released")
									active2.fields["criminal"] = "Discharged"
							investigate_log("[active1.fields["name"]] has been set from [old_field] to [active2.fields["criminal"]] by [usr.name] ([usr.key]).", "records")
							for(var/mob/living/carbon/human/H in mob_list) //thanks for forcing me to do this, whoever wrote this shitty records system
								H.sec_hud_set_security_status()
					if("Delete Record (Security) Execute")
						investigate_log("[usr.name] ([usr.key]) has deleted the security records for [active1.fields["name"]].", "records")
						if(active2)
							data_core.security -= active2
							qdel(active2)
							active2 = null

					if("Delete Record (ALL) Execute")
						if(active1)
							investigate_log("[usr.name] ([usr.key]) has deleted all records for [active1.fields["name"]].", "records")
							for(var/datum/data/record/R in data_core.medical)
								if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
									data_core.medical -= R
									qdel(R)
									break
							data_core.general -= active1
							qdel(active1)
							active1 = null

						if(active2)
							data_core.security -= active2
							qdel(active2)
							active2 = null
					else
						temp = "This function does not appear to be working at the moment. Our apologies."

	add_fingerprint(usr)
	updateUsrDialog()
	return

/obj/machinery/computer/secure_data/proc/get_photo(mob/user)
	var/obj/item/weapon/photo/P = null
	if(istype(user, /mob/living/silicon))
		var/mob/living/silicon/tempAI = user
		var/datum/picture/selection = tempAI.GetPhoto()
		if(selection)
			P = new()
			P.photocreate(selection.fields["icon"], selection.fields["img"], selection.fields["desc"])
	else if(istype(user.get_active_hand(), /obj/item/weapon/photo))
		P = user.get_active_hand()
	return P

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

	for(var/datum/data/record/R in data_core.security)
		if(prob(10/severity))
			switch(rand(1,8))
				if(1)
					if(prob(10))
						R.fields["name"] = "[pick(lizard_name(MALE),lizard_name(FEMALE))]"
					else
						R.fields["name"] = "[pick(pick(first_names_male), pick(first_names_female))] [pick(last_names)]"
				if(2)
					R.fields["sex"] = pick("Male", "Female")
				if(3)
					R.fields["age"] = rand(5, 85)
				if(4)
					R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Parolled", "Discharged")
				if(5)
					R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit")
				if(6)
					R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
				if(7)
					R.fields["species"] = pick(roundstart_species)
				if(8)
					var/datum/data/record/G = pick(data_core.general)
					R.fields["photo_front"] = G.fields["photo_front"]
					R.fields["photo_side"] = G.fields["photo_side"]
			continue

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

	..(severity)

/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2)
	if(user)
		if(authenticated)
			if(user.canUseTopic(src))
				if(!trim(message1))
					return 0
				if(!record1 || record1 == active1)
					if(!record2 || record2 == active2)
						return 1
	return 0


code:
/obj/machinery/computer/station_alert
	name = "station alert console"
	desc = "Used to access the station's automated alert system."
	icon_screen = "alert:0"
	icon_keyboard = "atmos_key"
	circuit = /obj/item/weapon/circuitboard/stationalert
	var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())

/obj/machinery/computer/station_alert/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
									datum/tgui/master_ui = null, datum/ui_state/state = default_state)
	ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
	if(!ui)
		ui = new(user, src, ui_key, "station_alert", name, 300, 500, master_ui, state)
		ui.open()

/obj/machinery/computer/station_alert/ui_data(mob/user)
	var/list/data = list()

	data["alarms"] = list()
	for(var/class in alarms)
		data["alarms"][class] = list()
		for(var/area in alarms[class])
			data["alarms"][class] += area

	return data

/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source)
	if(source.z != z)
		return
	if(stat & (BROKEN))
		return

	var/list/L = alarms[class]
	for(var/I in L)
		if (I == A.name)
			var/list/alarm = L[I]
			var/list/sources = alarm[3]
			if (!(source in sources))
				sources += source
			return 1
	var/obj/machinery/camera/C = null
	var/list/CL = null
	if(O && istype(O, /list))
		CL = O
		if (CL.len == 1)
			C = CL[1]
	else if(O && istype(O, /obj/machinery/camera))
		C = O
	L[A.name] = list(A, (C ? C : O), list(source))
	return 1

/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin)
	if(stat & (BROKEN))
		return
	var/list/L = alarms[class]
	var/cleared = 0
	for (var/I in L)
		if (I == A.name)
			var/list/alarm = L[I]
			var/list/srcs  = alarm[3]
			if (origin in srcs)
				srcs -= origin
			if (srcs.len == 0)
				cleared = 1
				L -= I
	return !cleared

/obj/machinery/computer/station_alert/process()
	..()

/obj/machinery/computer/station_alert/update_icon()
	..()
	if(stat & (NOPOWER|BROKEN))
		return
	var/active_alarms = FALSE
	for(var/cat in alarms)
		var/list/L = alarms[cat]
		if(L.len)
			active_alarms = TRUE
	if(active_alarms)
		overlays += "alert:2"


code:
#define NUKESCALINGMODIFIER 1

var/list/possible_uplinker_IDs = list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner")

/obj/machinery/computer/telecrystals
	name = "\improper Telecrystal assignment station"
	desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..."
	icon_state = "tcstation"
	icon_keyboard = "tcstation_key"
	icon_screen = "syndie"

/////////////////////////////////////////////
/obj/machinery/computer/telecrystals/uplinker
	name = "\improper Telecrystal upload/receive station"
	desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \
			you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant."
	var/obj/item/uplinkholder = null
	var/obj/machinery/computer/telecrystals/boss/linkedboss = null

/obj/machinery/computer/telecrystals/uplinker/New()
	..()

	var/ID
	if(possible_uplinker_IDs.len)
		ID = pick(possible_uplinker_IDs)
		possible_uplinker_IDs -= ID
		name = "[name] [ID]"
	else
		name = "[name] [rand(1,999)]"

/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/O, mob/user, params)
	if(istype(O, /obj/item))
		if(uplinkholder)
			user << "The [src] already has an uplink in it."
			return
		if(O.hidden_uplink)
			var/obj/item/I = user.get_active_hand()
			if(!user.drop_item())
				return
			uplinkholder = I
			I.loc = src
			I.add_fingerprint(user)
			update_icon()
			updateUsrDialog()
		else
			user << "The [O] doesn't appear to be an uplink..."

/obj/machinery/computer/telecrystals/uplinker/update_icon()
	..()
	if(uplinkholder)
		overlays += "[initial(icon_state)]-closed"

/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink()
	if(uplinkholder)
		uplinkholder.loc = get_turf(src.loc)
		uplinkholder = null
		update_icon()

/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1)
	if(uplinkholder && linkedboss)
		if(amt <= uplinkholder.hidden_uplink.telecrystals)
			uplinkholder.hidden_uplink.telecrystals -= amt
			linkedboss.storedcrystals += amt
			if(addLog)
				linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].")

/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1)
	if(uplinkholder && linkedboss)
		if(amt <= linkedboss.storedcrystals)
			uplinkholder.hidden_uplink.telecrystals += amt
			linkedboss.storedcrystals -= amt
			if(addLog)
				linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].")

///////

/obj/machinery/computer/telecrystals/uplinker/attack_hand(mob/user)
	if(..())
		return
	src.add_fingerprint(user)
	user.set_machine(src)

	var/dat = ""
	if(linkedboss)
		dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution.

"
	else
		dat += "No linked management consoles detected. Scan for uplink stations using the management console.

"

	if(uplinkholder)
		dat += "[uplinkholder.hidden_uplink.telecrystals] telecrystals remain in this uplink.
"
		if(linkedboss)
			dat += "Donate TC: 1 | 5"
		dat += "
Eject Uplink"

	var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Receive Station", 700, 500)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

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

	if(href_list["donate1"])
		donateTC(1)

	if(href_list["donate5"])
		donateTC(5)

	if(href_list["eject"])
		ejectuplink()

	src.updateUsrDialog()

/////////////////////////////////////////
/obj/machinery/computer/telecrystals/boss
	name = "team Telecrystal management console"
	desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \
	Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \
	based on the danger rating of the mission."
	icon_state = "computer"
	icon_screen = "tcboss"
	icon_keyboard = "syndie_key"
	var/virgin = 1
	var/scanrange = 10
	var/storedcrystals = 0
	var/list/TCstations = list()
	var/list/transferlog = list()

/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage)
	transferlog += ("[worldtime2text()] [logmessage]")

/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers()
	for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc))
		if(!A.linkedboss)
			TCstations += A
			A.linkedboss = src
	if(virgin)
		getDangerous()
		virgin = 0

/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population.
	..()
	var/danger
	danger = joined_player_list.len - ticker.mode.syndicates.len
	while(!IsMultiple(++danger,10))//Just round up to the nearest multiple of ten.
	scaleTC(danger)

/obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc.
	storedcrystals += amt * NUKESCALINGMODIFIER

/////////

/obj/machinery/computer/telecrystals/boss/attack_hand(mob/user)
	if(..())
		return
	src.add_fingerprint(user)
	user.set_machine(src)

	var/dat = ""
	dat += "Scan for TC stations.
"
	dat += "This [src] has [storedcrystals] telecrystals available for distribution.
"
	dat += "

"

	for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
		dat += "[A.name] | "
		if(A.uplinkholder)
			dat += "[A.uplinkholder.hidden_uplink.telecrystals] telecrystals."
		if(storedcrystals)
			dat+= "
Add TC: 1 | 5"
		dat += "
"

	if(TCstations.len)
		dat += "

Evenly distribute remaining TC.

"

	for(var/entry in transferlog)
		dat += "[entry]
"

	var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

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

	if(href_list["scan"])
		scanUplinkers()

	if(href_list["give1"])
		var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give1"])
		A.giveTC(1)

	if(href_list["give5"])
		var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give5"])
		A.giveTC(5)

	if(href_list["distrib"])
		var/sanity = 0
		while(storedcrystals && sanity < 100)
			for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
				A.giveTC(1,0)
			sanity++
		logTransfer("[src] evenly distributed telecrystals.")

	src.updateUsrDialog()
	return

#undef NUKESCALINGMODIFIER