Code Samples

I pride myself on clean, well written code that anyone should be able to read - even if they have little or no experience in the language the code is written in. I believe a well-written project can be taken over by anyone at any time with minimal overhead. I'm very strict about proper indentation and comments in my code.

NEW: Check out the poker game I'm working on!

Clock Control

A C# (WPF) Clock user control I created as a quick way for users to enter time with a single mouseclick.

Clock Control [download]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;

namespace AMR.MEDS.Prototype.Controls
{
	public class ClockControl : Control
	{

		#region private parts
		private int hours = 12;
		private int minutes = 0;
		private int padding = 20;
		private bool firstDigit = true;
		private string fontName = "Arial Black";
		#endregion

		#region public members
		public bool AM = true;
		public TimeSpan Value;
		public event EventHandler TimeChosen;
		public string TimeString
		{
			get { return getHourString(); }
		}
		#endregion

		#region color definitions
		Pen hourPen = new Pen(Brushes.Black, 4);
		Pen minutePen = new Pen(Brushes.Black, 2);
		Pen whitePen = new Pen(Brushes.White, 4);
		Pen thicker = new Pen(Brushes.Black, 2);
		Brush normalBackBrush = new LinearGradientBrush(new Rectangle(0, 0, 100, 600), Color.White,
				Color.Ivory, LinearGradientMode.Vertical);
		Brush backBrush;
		#endregion

		/// <summary>
		/// Constructor
		/// </summary>
		public ClockControl()
		{
			// double buffering, etc. 
			this.SetStyle(
			ControlStyles.UserPaint |
			ControlStyles.AllPaintingInWmPaint |
			ControlStyles.OptimizedDoubleBuffer |
			ControlStyles.ResizeRedraw, true);

			// events
			this.MouseDown	+= new MouseEventHandler(ClockControl_Mouse);
			this.MouseMove	+= new MouseEventHandler(ClockControl_Mouse);
			this.MouseUp	+= new MouseEventHandler(ClockControl_MouseUp);
			this.TimeChosen	+= new EventHandler(ClockControl_TimeChosen);
			this.KeyDown	+= new KeyEventHandler(ClockControl_KeyDown);
			this.KeyPress	+= new KeyPressEventHandler(ClockControl_KeyPress);

			// init background brush
			backBrush = normalBackBrush;
		}

		public string getHourString()
		{
			string hourstring = hours == 0 ? "12" : hours.ToString();
			hourstring += ":" + minutes.ToString().PadLeft(2, '0');
			return hourstring;
		}

		private void setHour(int h)
		{
			hours = h;
			Refresh();
		}

		private void setMinute(int m)
		{
			minutes = m;
			Refresh();
		}

		private void blinkRed()
		{
			Timer t = new Timer();
			t.Interval = 80;

			t.Tick += new EventHandler(t_Tick);
			backBrush = Brushes.Pink;
			Refresh();
			t.Start();
		}

		void t_Tick(object sender, EventArgs e)
		{
			backBrush = normalBackBrush;
			Refresh();
			((Timer)sender).Stop();
			((Timer)sender).Dispose();

		}

		#region Keyboard Stuff
		void ClockControl_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (char.IsNumber(e.KeyChar))
			{
				int digit = int.Parse(e.KeyChar.ToString());

				if (firstDigit)
				{
					if (digit >= 6)
					{
						blinkRed();
						return;
					}

					digit *= 10;
					firstDigit = false;
				}
				else
				{
					digit += minutes;
					setMinute(digit);
					TimeChosen(this, EventArgs.Empty);
					firstDigit = true;
				}
				setMinute(digit);
			}
		}

		void ClockControl_KeyDown(object sender, KeyEventArgs e)
		{

			Keys[] fKeys = new Keys[] { Keys.F1, Keys.F2, Keys.F3, Keys.F4, Keys.F5, 
				Keys.F6, Keys.F7, Keys.F8, Keys.F9, Keys.F10, Keys.F11, Keys.F12 };

			for (int i = 0; i < fKeys.Length; i++)
			{
				if (e.KeyData == fKeys[i])
				{
					setHour(i+1);
					firstDigit = true;
				}
			}
		}
		#endregion

		void ClockControl_TimeChosen(object sender, EventArgs e)
		{
			// do nothing
		}

		/// <summary>
		/// Here's where the magic happens.
		/// </summary>
		protected override void OnPaint(PaintEventArgs e)
		{
			// make it look nice
			e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

			// create a rectangle for the clock, just a lil smaller than the control area
			Rectangle surfaceRect = Rectangle.Inflate(ClientRectangle, -padding, -padding);

			// keep this thing square
			int rectSize = Math.Min(surfaceRect.Width, surfaceRect.Height);

			surfaceRect = new Rectangle((ClientRectangle.Width / 2) - (surfaceRect.Width / 2),
				surfaceRect.Y, rectSize, rectSize);

			// keep this thing centered
			surfaceRect.X = (ClientRectangle.Width / 2) - (surfaceRect.Width / 2);

			// create a light background shadow - nah it's ugly
			/*e.Graphics.FillEllipse(Brushes.LightGray, surfaceRect.X + 7, 
				surfaceRect.Y + 8, surfaceRect.Width, surfaceRect.Height);*/

			// don't paint if it's too small
			if (surfaceRect.Width < 20 || surfaceRect.Height < 20)
				return;

			// center point
			Point zero = new Point(surfaceRect.Left + (surfaceRect.Width / 2),
				surfaceRect.Top + (surfaceRect.Height / 2));

			// fill #1
			e.Graphics.FillEllipse(backBrush, surfaceRect);

			// border
			e.Graphics.DrawEllipse(thicker, surfaceRect);


			int tickLen = (int)(surfaceRect.Width * 0.45);
			int numLen = (int)(surfaceRect.Width * 0.35);
			int inflateSize = (int)(surfaceRect.Width * 0.07);

			// draw minute ticks
			for (int i = 0; i < 60; i++)
			{
				double currAngle = 2.0 * Math.PI * (i / 60.0);

				Point tickPt = new Point((int)(tickLen * Math.Sin(currAngle)),
							   (int)(-tickLen * Math.Cos(currAngle)));
				tickPt.X += zero.X;
				tickPt.Y += zero.Y;
				e.Graphics.DrawLine(Pens.Red, zero, tickPt);
			}

			Rectangle smallerRectangle = Rectangle.Inflate(surfaceRect,
				-inflateSize, -inflateSize);
			e.Graphics.FillEllipse(backBrush, smallerRectangle);

			// draw five minute (bigger) ticks and numbers
			for (int i = 0; i < 60; i += 5)
			{
				double currAngle = 2.0 * Math.PI * (i / 60.0);

				Point tickPt = new Point((int)(tickLen * Math.Sin(currAngle)),
							   (int)(-tickLen * Math.Cos(currAngle)));
				tickPt.X += zero.X;
				tickPt.Y += zero.Y;

				e.Graphics.DrawLine(thicker, zero, tickPt);
			}

			inflateSize /= 4;
			smallerRectangle.Inflate(-inflateSize, -inflateSize);
			e.Graphics.FillEllipse(backBrush, smallerRectangle);

			// draw numerals
			int numeral = 12;
			int numeralFontSize = Math.Max(1, inflateSize) * 4;
			Font numeralFont = new Font("Arial Black", numeralFontSize);
			for (int i = 0; i < 60; i += 5)
			{
				double currAngle = 2.0 * Math.PI * (i / 60.0);
				Point numeralPt = new Point((int)(numLen * Math.Sin(currAngle)),
				   (int)(-numLen * Math.Cos(currAngle)));

				numeralPt.X += zero.X;
				numeralPt.Y += zero.Y;

				StringFormat numFormat = new StringFormat();
				numFormat.Alignment = StringAlignment.Center;
				numFormat.LineAlignment = StringAlignment.Center;
				e.Graphics.DrawString(numeral.ToString(), numeralFont,
					Brushes.Black, numeralPt, numFormat);
				numeral = numeral == 12 ? 1 : numeral + 1;
			}

			// digital time display
			int fontSize = Math.Max(1, inflateSize + 3);
			Font f = new Font(fontName, fontSize);
			StringFormat sf = new StringFormat();
			sf.Alignment = StringAlignment.Center;
			e.Graphics.DrawString(getHourString(), f, Brushes.Black,
				zero.X, zero.Y - (zero.Y / 2), sf);

			// draw hour/minute hands
			double hourAngle = 2.0 * Math.PI * (hours + minutes / 60.0) / 12.0;
			double minuteAngle = 2.0 * Math.PI * (minutes / 60.0);
			int hourHandLen	= (int)(surfaceRect.Width * 0.33);
			int minuteHandLen = (int)(surfaceRect.Width * 0.45);
			Point hourPt = new Point((int)(hourHandLen * Math.Sin(hourAngle)),
							(int)(-hourHandLen * Math.Cos(hourAngle)));
			Point minutePt = new Point((int)(minuteHandLen * Math.Sin(minuteAngle)),
							(int)(-minuteHandLen * Math.Cos(minuteAngle)));
			
			hourPt.X += zero.X;
			hourPt.Y += zero.Y;
			minutePt.X += zero.X;
			minutePt.Y += zero.Y;
						
			e.Graphics.DrawLine(hourPen, zero, hourPt);
			e.Graphics.DrawLine(minutePen, zero, minutePt);

			// draw center dot
			int dotWidth = (int)(surfaceRect.Width * 0.05);
			e.Graphics.FillEllipse(Brushes.Black,
				new Rectangle(zero.X - (dotWidth / 2), zero.Y - (dotWidth / 2),
				dotWidth, dotWidth));
			e.Graphics.DrawEllipse(whitePen,
				new Rectangle(zero.X - (dotWidth / 2), zero.Y - (dotWidth / 2),
				dotWidth, dotWidth));
		}

		private void ClockControl_Mouse(object sender, MouseEventArgs e)
		{
			if (!(e.Button == MouseButtons.Left))
				return;
			Value = CalculateTimeFromPoint(e.X, e.Y);
			this.Refresh();
		}

		void ClockControl_MouseUp(object sender, MouseEventArgs e)
		{
			TimeChosen(this, EventArgs.Empty);
		}

		/// <summary>
		/// Figures out what time the user clicked.
		/// </summary>
		/// <param name="x">X-Coordinate of the clicked point</param>
		/// <param name="y">Y-Coordinate of the clicked point</param>
		private TimeSpan CalculateTimeFromPoint(int x, int y)
		{
			Point mid = new Point(ClientRectangle.Width / 2, ClientRectangle.Height / 2);
			Point p2 = new Point(x, y);
			double angle = (Math.Atan2(p2.Y - mid.Y, p2.X - mid.X) * 180.0 / Math.PI);
			angle += 90;
			if (angle < 0)
				angle = 270 + (90 - Math.Abs(angle));
			double percent = angle / 720;
			TimeSpan span = TimeSpan.FromMilliseconds(86400000 * percent);
			if (span.Hours == 0)
				span.Add(TimeSpan.FromHours(11));

			hours = span.Hours;
			minutes = span.Minutes;

			return span;
		}
	
		/// <summary>
		/// Calculates the angle between two points.
		/// </summary>
		protected double calcAngle(Point p1, Point p2)
		{
			double currRet = (Math.Atan2(p2.Y - p1.Y, p2.X - p1.X) * 180.0 / Math.PI);
			currRet += 90;

			if (currRet < 0)
				currRet = 270 + (90 - Math.Abs(currRet));
			return currRet;
		}
	}
}

PHR Controls

A series of controls created in JavaScript.

Global (Base Class) [download]
// ===========================================================================
//   PHR-Global - global phr types and super class
//      author: bfriedland
// ===========================================================================

var items = [];
var mapId = null;
var batchSize = 10;
var newDone = false;
var doWait = false;

function showNew() {
    if(!updateCheck()) return;
    if(contactType!='') {
        if(contactCount >= 5) {
            iBox.show(maximumItemsHTML());
            return;
        }
    }

    if($('name-')!=null) {
        setTimeout("$('name-').focus()", 1000);
    }
    
    if($('cond-body-').style.display == 'none') {
        if(Prototype.Browser.IE) { 
            // i hate ie. no fancy slides for you
            $('cond-body-').style.display = "block";
        } else { 
            new Effect.BlindDown('cond-body-');
        }
    }
    return false;
}

function showError(uuid, message) {
    console.log("Showing error: " + message);
    $('error-' + uuid).innerHTML += "&nbsp;&nbsp;&bull; "+message+"<br />";

    if($('error-' + uuid).style.display == 'none') {
        //new Effect.BlindDown('error-'+uuid, { duration: 1 });
        $('error-' + uuid).style.display = 'block';
    }

}

function resetError(uuid) {
    console.log("Resetting error.");
    $('error-' + uuid).innerHTML = "<b>There are errors in this entry which must be corrected:</b><br />";
}

function hideError(uuid) {
    console.log("Hiding error display.");
    resetError(uuid);
    if($('error-' + uuid).style.display=="none")
        return;
    new Effect.BlindUp('error-'+uuid, { duration: 0.5 });
}

function doSave(uuid) {
    for(var i=0;i<items.length;i++) {
        if(items[i].uuid == uuid) {
        items[i].save();
        }
    }
    return false;
}

function deletePrompt(uuid) {
    if(!updateCheck()) return;
    iBox.show(confirmDeleteBox(uuid));
}

function confirmDeleteBox(uuid) {
    var html = "<div class=\"popup-dialog\">"
        + "<h3>Delete Item?</h3>"
        + "<p>This action will permanently remove this item from your Emergency Medical Information Record (EMIR). </p>"
        + "<p>Are you sure you want to continue? </p>"
        + "<center><button onclick=\"doDelete('"+uuid+"'); iBox.hide();\">Delete</button> <button onclick=\"iBox.hide();\">Cancel</button></center>"
        + "</div>";
    return html;
}

function maximumItemsHTML() {
    var html = "<div class=\"popup-dialog\" style=\"height: 120px\">"
        + "<h3>List up to five total contacts</h3>"
        + "<p>Due to limited space, we can only list five emergency or medical contacts on your emergency medical information record (EMIR&reg;) summary. If you wish to add another emergency or medical contact, please remove an existing one first. </p>"
        + "<center><button onclick=\"iBox.hide();\" style=\"width: 75px; margin-top: 7px;\">Ok</button></center><br>"
        + "</div>";
    return html;
}


function doDelete(uuid) {
    for(var i=0;i<items.length;i++) {
        if(items[i].uuid == uuid) {
            items[i].remove();
            if(contactType!='') 
                contactCount--;
        }
    }
}

function saveCallBack(uuid) {
    console.log("saveCallBack(" + uuid + ")");
    getPHRItems();
}

function deleteCallBack(uuid) {
    console.log("deleteCallBack(): " + uuid);
    for(var i=0;i<items.length;i++) {
        if(items[i].uuid == uuid) {
            console.log("clearing item: " + uuid );
            items[i].clear();
        }
    }
}

function getPHRItems() {
    //$('meds-list-div').innerHTML = "<div align=\"center\"><img src=\"" + contextRoot + "/images/ajax-loader.gif\"></div>";
    console.log("HealthService.getPhrItemsIds("+memberID+", "+memberID+", "+categorySingle.toLowerCase()+", "+$('sort-order').value+", fillPHRItems);");
    if(doWait) { 
        console.log("Waiting one cycle for getPHRItems()"); 
        setTimeout("getPHRItems()", 200);
    }
    HealthService.getPhrItemsIds(memberID, memberID, categorySingle.toLowerCase(), $('sort-order').value, fillPHRItems);
}

function fillPHRItems(phrItems)  {
    $('meds-list-div').innerHTML = "";

    items = [];

    // create an empty one for adding new
    items[0] = new PHRItemItem("");

    // add the rest
    DWREngine.beginBatch();
    for(var i=0;i<phrItems.length;i++) {
        console.log("adding item: " + phrItems[i] )
        addPHRItemItem(phrItems[i]);

        // create a new batch every (batchSize) calls
        if(i%(batchSize)==batchSize-1) {
			DWREngine.endBatch();
			DWREngine.beginBatch();
		}
    }
    DWREngine.endBatch();
}

function addPHRItemItem(id) {
    items[items.length] = new PHRItemItem(id);
}

function fillPHRItem(anPHRItem) {
    for(var i=0;i<items.length;i++) {
        if(items[i].uuid == anPHRItem.id) {
            items[i].map(anPHRItem);
            items[i].redraw();
        }
    }
}

function bindAutoCompleter(context, uuid) {
    if(uuid+""==""&&(!newDone)) {
        newDone = true;
        console.log("Delayed binding of new autocompleter...");
        setTimeout("bindAutoCompleter('"+context+"', '')", 500);
        return;
    }
    if(newDone = true)
        newDone = false;

    jQuery("#name-"+uuid).autocomplete(pickListURL+"/suggest", {
        dataType: "jsonp",
        width: 300,
        extraParams: {ctx: context },
        minChars: 1,
        max: 20,
        scroll: false,
        delay: 200,
        multiple: false,
        multipleSeparator: "|",
        parse: function(response) {
            $("code-"+uuid).value = "";
            return jQuery.map(response.suggestions.terms, function(term) {
                return {
                    data: term,
                    value: term.code ,
                    result: term.name
                }
            });
        },
        formatItem: function(term) {
            return term.name;
        }
    }).result(function(e, term) {
        if(term==null) {
            console.warn("Unrecognized term selected.");
            return;
        }
        console.log("Selected: " + term.name + " (" + term.code + ")");
        $("name-"+uuid).value = term.name;
        $("code-"+uuid).value = term.code;
    });
}


// super class for phr items
var PhrItem = Class.create({
    initialize: function(uuid) {
        this.uuid = uuid;
        $('meds-list-div').innerHTML += "<div id='body-"+this.uuid+"' class='item-container'></div>";
        this.body = $('body-'+this.uuid);
        this.requery(this.uuid, this.body);
    }
})
Allergies [download]
// ===========================================================================
//   Allergies PHR Item Type
//      author: bfriedland
// ===========================================================================

var defaultContext = "AT";

// list of different possible severity types
var severityTypes = ["mild", "moderate", "anaphylactic"];
var reactionTypes = ["abdominal pain", "abdominal swelling", "abnormal blood clotting",
    "abnormal reflexes", "abnormal thirst", "blood infection", "chest pain", "constipation",
    "cough", "coughing up blood", "diarrhea", "dizziness", "easy bruising",
    "elevated liver enzymes", "enlarged glands", "excessive crying of infant",
    "excessive sleeping", "facial weakness", "fainting", "fast breathing", "fast heart rate",
    "fatigue", "fever", "flushing", "frequent urination", "gas", "green or yellow phlegm",
    "growth problem", "hallucinations", "headache", "hearing changes", "heart murmur",
    "heart palpitations", "heartburn", "hiccough", "high blood pressure", "hyperventilation",
    "insomnia", "jaundice or yellow skin", "lack of coordination", "leakage of stool",
    "leakage of urine", "loss of appetite", "low blood count", "low blood pressure",
    "memory loss", "muscle aches", "nausea and vomiting", "nausea only", "noisy breathing",
    "nosebleed", "numbness or tingling", "painful breathing", "painful urination", "paleness",
    "paralysis", "problem walking", "rash", "reduced urination", "retention of urine", "seizures",
    "shock", "shortness of breath", "smell or taste disturbance", "speech problem", "stiff neck",
    "swallowing problem", "sweating", "swelling", "throat pain", "twitching", "unconsciousness",
    "visual changes", "voice problem", "vomiting only", "weakness", "weight gain", "weight loss",
    "wheezing"];

var PHRItemItem = Class.create(PhrItem, {

    initialize: function($super, uuid) {
        $super(uuid);
    },
    requery: function(uuid) {
        console.log("requery: " + uuid);
        var item = this;
        item.uuid = uuid;
        if(this.uuid + "" != "") {
            HealthService.getPhrItem(memberID, memberID, item.uuid, "allergy", fillPHRItem);
        } else {
            
            var emptyItem = { id:null, name:null, comments:null, ageOfOnset:null, assocMedicalComment:null, code:null, context:null, displayedOnId:null, noKnownPHRItem:null, reaction:null, severity:null };
            this.map(emptyItem);
            this.redraw();
        }
    },
    map: function(phritem) {
        this.name = (phritem.name!=null)?phritem.name:"";
        this.comments = phritem.comments;
        this.ageOfOnset = phritem.ageOfOnset;
        this.assocMedicalComment = phritem.assocMedicalComment;
		this.code = (phritem.code!=null)?phritem.code:"";
        this.context = (phritem.context!=null)?phritem.context:"";
        this.displayedOnId = phritem.displayedOnId;
        this.noKnownPHRItem = phritem.noKnownPHRItem;
        this.reaction = (phritem.reaction!=null)?phritem.reaction:"";
        this.severity = (phritem.severity!=null)?phritem.severity:"";
        try {
            this.created = phritem.dateCreated+"";
            this.created = this.created.split('00:')[0];
        } catch(e) {}
        try { 
            this.modified = formatDate(phritem.dateModified);
        } catch(e) {}
    },
    save: function() {
        // map to phritem
        var phritem = { id:null, name:null, comments:null, ageOfOnset:null, assocMedicalComment:null, code:null, context:null, displayedOnId:null, noKnownPHRItem:null, reaction:null, severity:null };
        phritem.id = this.uuid;
        phritem.name = this.name;
        phritem.comments = this.comments;
        phritem.ageOfOnset = this.ageOfOnset;
        phritem.assocMedicalComment = this.assocMedicalComment;

        console.log("context: " + defaultContext);

        phritem.context = ((this.context==null||this.context=="")?defaultContext:this.context);

        console.log("this.context: " + this.context);
        console.log("phritem.context: " + phritem.context);

        phritem.displayedOnId = this.displayedOnId;
        phritem.noKnownPHRItem = this.noKnownPHRItem;
        phritem.reaction = this.reaction;
        phritem.code = this.code;
        
        // get values from controls
        phritem.name = $('name-'+this.uuid).value;
        phritem.severity = $('severity-'+this.uuid).value;
        phritem.reaction = $('reaction-'+this.uuid).value;
		resetError(this.uuid);

		// only assign a code if a new code has been populated in the hidden control
		if($('code-'+this.uuid).value+""!="") {
			console.log("code assigned");
            phritem.code = $('code-'+this.uuid).value;
        } else {
			console.log("no code assigned - throwing error");
			showError(this.uuid, "Name not recognized, please choose from available options. ");
			return;
		}
        if($('context-'+this.uuid).value+""!="") {
            phritem.context = $('context-'+this.uuid).value;
        }

        console.log("about to save a phritem");
        console.log(phritem);

        this.map(phritem);

        // save phritem
        dwr.engine.beginBatch();
        HealthService.saveAllergy(memberID, memberID, phritem, "allergy", saveCallBack);
        dwr.engine.endBatch({
            errorHandler:function(msg, exc){
                //alert('error id = '+exc.errId);
                errorPrompt();
            }
        });
    },
    redraw: function() {
        var item = this;
        var html = "<div id=\"cond-"+item.body.id+"\" ";
        var isNew = (item.uuid + "" == "");

        
        if(isNew) {
            html += "style=\"display: none;\" class=\"single-med edit\" ";
        } else {
            html += "class=\"single-med\" ";
        }

        html += ">"
            + "	<div class=\"single-med-header clearfix\">"
            + "		<div class=\"med-name\">"
            + "			<h4>"+item.name+"</h4>"
            + "			<p>Last Updated: " + this.modified + " </p>"
            + "		</div>"
            + "		<div class=\"condition-onset\" style=\"font-size: 10px; color: #666666\">";
        if(item.severity!="") {
            html += "			<p><b>Severity:</b><br /> " + item.severity + "</p>";
        }
        if(item.reaction!="") {
            html += "			<p><b>Reaction:</b><br /> " + item.reaction + "</p>";
        }

        html +=  "		</div>"
            + "		<div class=\"med-tools\">"
            + "			<p class=\"edit-link edit-delete-buttons\"><a href=\"#\"><img alt=\"Edit this item\" src=\"" + contextRoot + "/images/edit_button.png\" /></a></p>"
            + "			<p class=\"edit-delete-buttons\"><a href=\"#\" onclick=\"deletePrompt('"+item.uuid+"');\"><img alt=\"Delete this item\" src=\"" + contextRoot + "/images/delete_button.png\" /></a></p>"
            + "		</div>"
            + "	</div><!--/single-med-header-->"
            + "	<div class=\"edit-med-wrapper\">";

        if(isNew) {
            html += "		<h4>New Allergy</h4>";
        } else {
            html += "		<h4>Editing: "+item.name+"</h4>";
        }
        html += "		<form class=\"two-column edit-med-form\" method=\"post\" action=\"#\" onsubmit=\"return false\">"
            + "		<div class=\"inner\">"
            + "		<fieldset>"
            + "			<div id=\"error-"+item.uuid+"\" style=\"display: none;\" class=\"error-box\"><b>There are errors in this entry which must be corrected:</b><br /></div>"
            + "			<table cellspacing=\"0\"><tbody>"
            + "             <tr>"
            + "                 <td class=\"left\"><label for=\"conditionname01\">Allergy Name:</label></td>"
            + "                 <td><input type=\"text\" value=\""+item.name+"\" id=\"name-"+item.uuid+"\" autocomplete=\"off\" onblur=\"jQuery('#'+this.id).search();\" /></td>"
            + "             </tr>"
            + "			</tbody></table>"
            + "		</fieldset>"
            + "		<fieldset>"
            + "         <h4 style=\"color:#4e764a; padding-left:0px; padding-top:2px\">Recommended</h4>"
            + "			<table cellspacing=\"0\"><tbody>"
            + "			<tr>"
            + "				<td class=\"left\"><label for=\"onset01\">Severity:</label></td>"
            + "				<td>"
            + "                 <select id=\"severity-"+item.uuid+"\">";

        for(var i=0;i<severityTypes.length;i++) {
            html += "<option value=\""+severityTypes[i]+"\"";
            if(item.severity.toLowerCase()==severityTypes[i].toLowerCase()) html += " selected "
            html += ">"+severityTypes[i]+"</option>";
        }
        
        html += "                 </select>"
            + "             </td>"
            + "			</tr>"
            + "			<tr>"
            + "				<td class=\"left\"><label for=\"onset01\">Reaction:</label></td>"
            + "				<td>"
            + "                 <select id=\"reaction-"+item.uuid+"\">"
            + "                     <option value=\"\">-Select-</option>";

        for(var i=0;i<reactionTypes.length;i++) {
            html += "<option value=\""+reactionTypes[i]+"\"";
            if(item.reaction.toLowerCase()==reactionTypes[i].toLowerCase()) html += " selected "
            html += ">"+reactionTypes[i]+"</option>";
        }

        html += "                 </select>"
            + "             </td>"
            + "			</tr>"
            + "			</tbody></table>"
            + "         <input type=\"hidden\" id=\"code-"+item.uuid+"\"  value=\""+item.code+"\">"
            + "         <input type=\"hidden\" id=\"context-"+item.uuid+"\" value=\""+item.context+"\">"
            + "		</fieldset>";

		if(item.comments!=null && !isNew) {
			html += "<div style=\"margin: 10px;\">"
				+ "	<label><b>Additional Information*</b></label>"
				+ "	<p style=\"padding-left: 10px;\">"+item.comments+"</p>"
				+ "	<p style=\"padding-left: 10px; font-size: 80%;\"><i>* This information also appears on your Emergency Medical Information Record. If you need to make any changes, please call us at 888-633-4298.</i> </p>";
				+ "</div>";
		}

        html += "		<fieldset>"
            + "			<table cellspacing=\"0\"><tbody>"
            + "			<tr>"
            + "				<td class=\"left\">&nbsp;</td>"
            + "				<td class=\"buttons\">";
        if(!isNew) {
            html += "					<a href=\"#\" class=\"cancel-edit\" onclick=\"$$('form').each(function(el) { el.reset(); });\">Cancel</a>";
        } else {
            html += "					<a href=\"#\" class=\"cancel-edit-no-function\" onclick=\"new Effect.BlindUp('cond-body-'); return false;\">Cancel</a>";
        }
        html+=
              "					<a href=\"#\" onclick=\"doSave('"+item.uuid+"');\"><img alt=\"Save changes\" src=\"" + contextRoot + "/images/btn-save.png\" /></a>"
            + "				</td>"
            + "			</tr>"
            + "			</tbody></table>"
            + "		</fieldset>";
        if(!isNew) { html +=
                "		<fieldset>"
                + "			<p><a href=\"#\" onclick=\"deletePrompt('"+item.uuid+"');\">Remove from list</a>.</p>"
                + "		</fieldset>";
        }
        html +=
              "		</div><!--/inner-->"
            + "		</form>"
            + "	</div><!--/edit-med-wrapper-->"
            + "</div><!--/single-med-->";

        // draw it 
        $(item.body.id).innerHTML = html;

        // create the picklist autocompleter stuff
        bindAutoCompleter(defaultContext, item.uuid);

        // for some strange reason, init clicks needs to be called
        //   half a second after the control is drawn. don't ask me why.
        setTimeout("initClicks()", 500);

    },
    remove: function() {
        console.log("HealthService.deletePhrItem("+memberID+", "+memberID+", "+this.uuid+", allergy, deleteCallBack);");
        HealthService.deletePhrItem(memberID, memberID, this.uuid, "allergy", deleteCallBack);
    }, 
    clear: function() {
        $(this.body.id).innerHTML = "";
    },
    reset: function() {
        $('name-'+this.uuid).value = "";
        $('severity-'+this.uuid).value = "";
        $('reaction-'+this.uuid).value = "";
		$('code-'+this.uuid).value = "";
        $('context-'+this.uuid).value = "";
		resetError(this.uuid);
		hideError(this.uuid);
    }
});
Medications [download]
// ===========================================================================
//   Medications PHR Item Type
//      author: bfriedland
// ===========================================================================

var defaultContext = "TA";

// list of different possible severity types
var unitTypes = ["CAPSULE(S)", "DROP(S)", "GRAMS", "IU", "MCG", "MEQ", "MG", "MG/KG", "ML(S)", "PATCH(S)", "PUFFS", "SPRAYS", "TABLET(S)", "TBSP(S)", "TSP(S)", "UNIT(S)"];
var frequencyTypes = ["HOUR", "DAY", "WEEK", "MONTH", "AS NEEDED"];

var frequencyOptions = new Array();
frequencyOptions[0] = ["1 time per day", 1, "DAY"];
frequencyOptions[1] = ["2 times per day", 2, "DAY"];
frequencyOptions[2] = ["3 times per day", 3, "DAY"];
frequencyOptions[3] = ["4 times per day", 4, "DAY"];
frequencyOptions[4] = ["every hour", 1, "HOUR"];
frequencyOptions[5] = ["every 2 hours", 2, "HOUR"];
frequencyOptions[6] = ["every 3 hours", 3, "HOUR"];
frequencyOptions[7] = ["every 4 hours", 4, "HOUR"];
frequencyOptions[8] = ["every 6 hours", 6, "HOUR"];
frequencyOptions[9] = ["every 8 hours", 8, "HOUR"];
frequencyOptions[10] = ["every 12 hours", 12, "HOUR"];
frequencyOptions[11] = ["every 24 hours", 24, "HOUR"];
frequencyOptions[12] = ["every other day", 4, "WEEK"];
frequencyOptions[13] = ["1 time per week", 1, "WEEK"];
frequencyOptions[14] = ["every two weeks", 2, "MONTH"];
frequencyOptions[15] = ["1 time per month", 1, "MONTH"];
frequencyOptions[16] = ["as neeeded", 1, "AS NEEDED"];

var PHRItemItem = Class.create(PhrItem, {

    initialize: function($super, uuid) {
        $super(uuid);
    },
    requery: function(uuid) {
        console.log("requery: " + uuid);
        var item = this;
        item.uuid = uuid;
        if(this.uuid + "" != "") {
            HealthService.getPhrItem(memberID, memberID, item.uuid, "medication", fillPHRItem);
        } else {
            var emptyItem = {id:null, name:null, comments:null, ageOfOnset:null, assocMedicalComment:null, code:null, context:null, displayedOnId:null, noKnownPHRItem:null, medicationStartedOn:null, medicationEndsOn:null, reasonOfPrescribed:null, prescribedBy:null, formOfMedication:null, quantityDispensed:null, strengthValue:null, strengthUnitOfMeasure:null, strengthNote:null, dosageValue:null, dosageUnitOfMeasure:null, dosageNote:null, frequencyValue:null, frequencyUnitOfMeasure:null, frequencyNote:null };
            this.map(emptyItem);
            this.redraw();
        }
    },
    map: function(phritem) {
        console.log("mapping medication...");
        this.name = (phritem.name!=null)?phritem.name:"";
        this.comments = phritem.comments;
        this.ageOfOnset = (phritem.ageOfOnset!=null)?phritem.ageOfOnset:"";
        this.assocMedicalComment = phritem.assocMedicalComment;
		this.code = (phritem.code!=null)?phritem.code:"";
        this.context = (phritem.context!=null)?phritem.context:"";
        this.displayedOnId = phritem.displayedOnId;
        this.noKnownPHRItem = phritem.noKnownPHRItem;

        this.manufacturerName = (phritem.manufacturerName!=null)?phritem.manufacturerName:"";
        this.description = phritem.description;
        this.dateOfImplant = phritem.dateOfImplant;
        this.location = phritem.location;
        this.modelNumber = (phritem.modelNumber!=null)?phritem.modelNumber:"";
        this.serialNumber = (phritem.serialNumber!=null)?phritem.serialNumber:"";


        this.medicationStartedOn = phritem.medicationStartedOn;
        this.medicationEndsOn = phritem.medicationEndsOn;
        this.reasonOfPrescribed = phritem.reasonOfPrescribed;
        this.prescribedBy = phritem.prescribedBy;
        this.formOfMedication = phritem.formOfMedication;
        this.quantityDispensed = phritem.quantityDispensed;
        this.strengthValue = phritem.strengthValue;
        this.strengthUnitOfMeasure = phritem.strengthUnitOfMeasure;
        this.strengthNote = phritem.strengthNote;
        this.dosageValue = (phritem.dosageValue!=null)?phritem.dosageValue:"";
        this.dosageUnitOfMeasure = (phritem.dosageUnitOfMeasure!=null)?phritem.dosageUnitOfMeasure:"";
        this.dosageNote = phritem.dosageNote;
        this.frequencyValue = (phritem.frequencyValue!=null)?phritem.frequencyValue:"";
        this.frequencyUnitOfMeasure = (phritem.frequencyUnitOfMeasure!=null)?phritem.frequencyUnitOfMeasure:"";
        this.frequencyNote = phritem.frequencyNote;

        try {
            this.created = phritem.dateCreated+"";
            this.created = this.created.split('00:')[0];
        } catch(e) {}
        try { 
            this.modified = formatDate(phritem.dateModified);
        } catch(e) {}
    },
    save: function() {
        // map to phritem
        var phritem = {id:null, name:null, comments:null, ageOfOnset:null, assocMedicalComment:null, code:null, context:null, displayedOnId:null, noKnownPHRItem:null, medicationStartedOn:null, medicationEndsOn:null, reasonOfPrescribed:null, prescribedBy:null, formOfMedication:null, quantityDispensed:null, strengthValue:null, strengthUnitOfMeasure:null, strengthNote:null, dosageValue:null, dosageUnitOfMeasure:null, dosageNote:null, frequencyValue:null, frequencyUnitOfMeasure:null, frequencyNote:null };
        phritem.id = this.uuid;
        phritem.name = this.name;
        phritem.comments = this.comments;
        phritem.ageOfOnset = this.ageOfOnset;
        phritem.assocMedicalComment = this.assocMedicalComment;
        phritem.context = ((this.context==null||this.context=="")?defaultContext:this.context);
        phritem.displayedOnId = this.displayedOnId;
        phritem.noKnownPHRItem = this.noKnownPHRItem;
        phritem.code = this.code;


        phritem.medicationStartedOn = this.medicationStartedOn;
        phritem.medicationEndsOn = this.medicationEndsOn;
        phritem.reasonOfPrescribed = this.reasonOfPrescribed;
        phritem.prescribedBy = this.prescribedBy;
        phritem.formOfMedication = this.formOfMedication;
        phritem.quantityDispensed = this.quantityDispensed;
        phritem.strengthValue = this.strengthValue;
        phritem.strengthUnitOfMeasure = this.strengthUnitOfMeasure;
        phritem.strengthNote = this.strengthNote;
        phritem.dosageValue = this.dosageValue;
        phritem.dosageUnitOfMeasure = this.dosageUnitOfMeasure;
        phritem.dosageNote = this.dosageNote;
        phritem.frequencyValue = this.frequencyValue;
        phritem.frequencyUnitOfMeasure = this.frequencyUnitOfMeasure;
        phritem.frequencyNote = this.frequencyNote;
       
        // get values from controls
        phritem.name = $('name-'+this.uuid).value;
        phritem.dosageValue = $('dosageValue-'+this.uuid).value;
        phritem.dosageUnitOfMeasure = $('dosageUnit-'+this.uuid).value;
        phritem.frequencyValue = $('frequencyValue-'+this.uuid).value;
        phritem.frequencyUnitOfMeasure = $('frequencyUnit-'+this.uuid).value;

		resetError(this.uuid);

        // only assign a code if a new code has been populated in the hidden control
		if($('code-'+this.uuid).value+""!="") {
			console.log("code assigned");
            phritem.code = $('code-'+this.uuid).value;
        } else {
			console.log("no code assigned - throwing error");
			showError(this.uuid, "Name not recognized, please choose from available options. ");
			return;
		}

        console.log("about to save a phritem");
        console.log(phritem);

        this.map(phritem);

        // save phritem
        console.log("HealthService.saveMedication("+memberID+", "+memberID+", phritem, medication, saveCallBack);");
        console.log(phritem);
        dwr.engine.beginBatch();
        HealthService.saveMedication(memberID, memberID, phritem, "medication", saveCallBack);
        dwr.engine.endBatch({
            errorHandler:function(msg, exc){
                //alert('error id = '+exc.errId);
                errorPrompt();
            }
        });
    },
    redraw: function() {
        var item = this;
        var html = "<div id=\"cond-"+item.body.id+"\" ";
        var isNew = (item.uuid + "" == "");

        
        if(isNew) {
            html += "style=\"display: none;\" class=\"single-med edit\" ";
        } else {
            html += "class=\"single-med\" ";
        }

        var frequencyString = null;

//        for(var i=0;i<frequencyOptions.length;i++) {
//            if(item.frequencyUnitOfMeasure.toLowerCase()==frequencyOptions[i][2].toLowerCase()
//                && item.frequencyValue==frequencyOptions[i][1]) {
//                frequencyString = frequencyOptions[i][0];
//            }
//        }

        html += ">"
            + "	<div class=\"single-med-header clearfix\">"
            + "		<div class=\"med-name\">"
            + "			<h4>"+item.name+"</h4>"
            + "			<p>Last Updated: " + this.modified + " </p>"
            + "		</div>"
            + "		<div class=\"condition-onset\" style=\"font-size: 10px; color: #666666\">";
        if(item.dosageValue!="") {
            html += "         <p><b>Dosage:</b><br /> " + item.dosageValue + " " + item.dosageUnitOfMeasure + "</p>";
        }

        if(frequencyString!=null ) {
            html += "         <p><b>How Often:</b><br /> " + frequencyString + "</p>"
        } else if(item.frequencyValue!=""||item.frequencyUnitOfMeasure=="AS NEEDED") {
            html += "         <p><b>How Often:</b><br /> " + item.frequencyValue + ((item.frequencyUnitOfMeasure=="AS NEEDED")?"":" / ") + item.frequencyUnitOfMeasure + "</p>";
        }
        html += "		</div>"
            + "		<div class=\"med-tools\">"
            + "			<p class=\"edit-link edit-delete-buttons\"><a href=\"#\"><img alt=\"Edit this item\" src=\"" + contextRoot + "/images/edit_button.png\" /></a></p>"
            + "			<p class=\"edit-delete-buttons\"><a href=\"#\" onclick=\"deletePrompt('"+item.uuid+"');\"><img alt=\"Delete this item\" src=\"" + contextRoot + "/images/delete_button.png\" /></a></p>"
            + "		</div>"
            + "	</div><!--/single-med-header-->"
            + "	<div class=\"edit-med-wrapper\">";

        if(isNew) {
            html += "		<h4>New Medication</h4>";
        } else {
            html += "		<h4>Editing: "+item.name+"</h4>";
        }
        html += "		<form class=\"two-column edit-med-form\" method=\"post\" action=\"#\" onsubmit=\"return false\">"
            + "		<div class=\"inner\">"
            + "		<fieldset>"
            + "			<div id=\"error-"+item.uuid+"\" style=\"display: none;\" class=\"error-box\"><b>There are errors in this entry which must be corrected:</b><br /></div>"
            + "			<table cellspacing=\"0\"><tbody>"
            + "             <tr>"
            + "                 <td class=\"left\"><label for=\"conditionname01\">Medication Name:</label></td>"
            + "                 <td><input type=\"text\" value=\""+item.name+"\" id=\"name-"+item.uuid+"\" autocomplete=\"off\" onblur=\"jQuery('#'+this.id).search();\" /></td>"
            + "             </tr>"
            + "			</tbody></table>"
            + "		</fieldset>"
            + "		<fieldset>"
            + "         <h4 style=\"color:#4e764a; padding-left:0px; padding-top:2px\">Recommended</h4>"
            + "			<table cellspacing=\"0\"><tbody>"
            /* DOSAGE */
            + "			<tr>"
            + "				<td class=\"left\" valign=\"top\"><label for=\"dosageValue-"+item.uuid+"\">Dosage:</label></td>"
            + "				<td>"
            + "                 <input type=\"text\" value=\""+item.dosageValue+"\" id=\"dosageValue-"+item.uuid+"\" length=\"7\" style=\"width: 50px;\" />"
            + "                 <select id=\"dosageUnit-"+item.uuid+"\">"
            + "                     <option value=\"\">-Select-</option>";

        for(var i=0;i<unitTypes.length;i++) {
            html += "<option value=\""+unitTypes[i]+"\"";
            if(item.dosageUnitOfMeasure.toLowerCase()==unitTypes[i].toLowerCase()) html += " selected ";
            html += ">"+unitTypes[i]+"</option>";
        }

        html += "                 </select>"
            + "             </td>"
            + "			</tr>"

            /* HOW OFTEN  */
            + "			<tr>"
            + "				<td class=\"left\" valign=\"top\"><label for=\"dosageValue-"+item.uuid+"\">How Often:</label></td>"
            + "				<td>"
//            + "                 <select id=\"howOften-"+item.uuid+"\" onchange=\"howOftenChanged('"+item.uuid+"');\">"
//            + "                     <option value=\"\">-Select-</option>";
        var foundOne = false;
//        for(var i=0;i<frequencyOptions.length;i++) {
//            html += "<option value=\""+frequencyOptions[i][1]+"|"+frequencyOptions[i][2]+"\"";
//            if(item.frequencyUnitOfMeasure.toLowerCase()==frequencyOptions[i][2].toLowerCase()
//                && item.frequencyValue==frequencyOptions[i][1]) {
//                foundOne = true;
//                html += " selected ";
//            }
//            html += ">"+frequencyOptions[i][0]+"</option>";
//        }
//
//        html += "                   <option value=\"other\" "+(((!foundOne)&&item.frequencyValue!="")?"selected":"")+">other</option>"
//            + "                 </select>"
            html+= "                 <div id=\"frequencyRow-"+item.uuid+"\" style=\""+(((!foundOne)&&item.frequencyValue!="")?"":"")+"padding-top: 0px;\">"
            + "                     <input type=\"text\" value=\""+item.frequencyValue+"\" id=\"frequencyValue-"+item.uuid+"\" length=\"7\" style=\"width: 50px;\" />"
            + "                     <select id=\"frequencyUnit-"+item.uuid+"\">"
            + "                         <option value=\"\">-Select-</option>";

        for(var i=0;i<frequencyTypes.length;i++) {
            html += "<option value=\""+frequencyTypes[i]+"\"";
            if(item.frequencyUnitOfMeasure.toLowerCase()==frequencyTypes[i].toLowerCase()) html += " selected ";
            html += ">"+frequencyTypes[i]+"</option>";
        }

        html += "                 </select>"
            + "                 </div>"
            + "             </td>"
            + "			</tr>"
            + "			</tbody></table>"
            + "         <input type=\"hidden\" id=\"code-"+item.uuid+"\" value=\""+item.code+"\">"
            + "		</fieldset>";

		if(item.comments!=null && !isNew) {
			html += "<div style=\"margin: 10px;\">"
				+ "	<label><b>Additional Information*</b></label>"
				+ "	<p style=\"padding-left: 10px;\">"+item.comments+"</p>"
				+ "	<p style=\"padding-left: 10px; font-size: 80%;\"><i>* This information also appears on your Emergency Medical Information Record. If you need to make any changes, please call us at 888-633-4298.</i> </p>";
				+ "</div>"
		}

        html += "		<fieldset>"
            + "			<table cellspacing=\"0\"><tbody>"
            + "			<tr>"
            + "				<td class=\"left\">&nbsp;</td>"
            + "				<td class=\"buttons\">";
        if(!isNew) {
            html += "					<a href=\"#\" class=\"cancel-edit\" onclick=\"$$('form').each(function(el) { el.reset(); });\">Cancel</a>";
        } else {
            html += "					<a href=\"#\" class=\"cancel-edit-no-function\" onclick=\"new Effect.BlindUp('cond-body-'); return false;\">Cancel</a>";
        }
        html+=
              "					<a href=\"#\" onclick=\"doSave('"+item.uuid+"');\"><img alt=\"Save changes\" src=\"" + contextRoot + "/images/btn-save.png\" /></a>"
            + "				</td>"
            + "			</tr>"
            + "			</tbody></table>"
            + "		</fieldset>";
        if(!isNew) {html +=
                "		<fieldset>"
                + "			<p><a href=\"#\" onclick=\"deletePrompt('"+item.uuid+"');\">Remove from list</a>.</p>"
                + "		</fieldset>";
        }
        html +=
              "		</div><!--/inner-->"
            + "		</form>"
            + "	</div><!--/edit-med-wrapper-->"
            + "</div><!--/single-med-->";

        // draw it 
        $(item.body.id).innerHTML = html;

        // create the picklist autocompleter stuff
        bindAutoCompleter(defaultContext, item.uuid);

        // for some strange reason, init clicks needs to be called
        //   half a second after the control is drawn. don't ask me why.
        setTimeout("initClicks()", 500);
    },
    remove: function() {
        console.log("HealthService.deletePhrItem("+memberID+", "+memberID+", "+this.uuid+", medication, deleteCallBack);");
        HealthService.deletePhrItem(memberID, memberID, this.uuid, "medication", deleteCallBack);
    }, 
    clear: function() {
        $(this.body.id).innerHTML = "";
    },
    reset: function() {
        $('name-'+this.uuid).value = "";
        $('dosageValue-'+this.uuid).value = "";
        $('frequencyValue-'+this.uuid).value = "";
		$('code-'+this.uuid).value = "";
		resetError(this.uuid);
		hideError(this.uuid);
    }
});

function howOftenChanged(uuid) {
    $('frequencyRow-'+uuid).style.display = ($('howOften-'+uuid).value=="other")?"block":"none";
    if($('howOften-'+uuid).value.split("|").length>1) {
        $('frequencyValue-'+uuid).value = $('howOften-'+uuid).value.split("|")[0];
        for(var i=0;i<$('frequencyUnit-'+uuid).options.length;i++) {
            if($('frequencyUnit-'+uuid).options[i].value == $('howOften-'+uuid).value.split("|")[1]) {
                $('frequencyUnit-'+uuid).selectedIndex = i;
                break;
            }
        }
    } else {
        $('frequencyValue-'+uuid).value = "";
        $('frequencyUnit-'+uuid).selectedIndex = 0;
    }
}

Test Grounds

An example of a C# daemon written for emergency services.

TestGrounds.cs [download]
/**********************************************************************************************
@author  Ben Friedland
@version 1.0
Name of the File               :  Program.cs
Creation/Modification History  :
								  17-APR-2007     Created

This is the interface for extracting data from Tracy Fire and writing it out to a 
fixed format, fixed length file. 
*********************************************************************************************
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.IO;
using System.Xml;

namespace TestGrounds {
	class Program {

		private static XmlDocument xdoc;
		private static string masterIncidentNum;

		static void Main(string[] args) {
			XmlNode definitionNode;
			string connStr = Properties.Settings.Default.Connection;
			string incidentID = "185627";
			string sql = "SELECT TOP 1 i.*, v.Response_Number " +
				"FROM Response_Master_Incident i " +
				"LEFT JOIN Response_Vehicles_Assigned v ON " +
				"i.ID = v.Master_Incident_ID " +
				"WHERE i.ID = @incidentID\r\n " +
				"SELECT TOP 100 * FROM Response_Comments " +
				"WHERE Master_Incident_ID = @incidentID\r\n " +
				"SELECT TOP 10 * FROM Response_Transports " +
				"WHERE Master_Incident_ID = @incidentID\r\n " +
				"SELECT * FROM Response_Vehicles_Assigned rva " +
				"LEFT JOIN Response_Vehicles_Personnel rvp ON " +
				"rva.ID = rvp.Veh_Assigned_ID " +
				"LEFT JOIN Response_Transports rt ON " +
				"rva.ID = rt.Vehicle_Assigned_ID " +
				"WHERE rva.Master_Incident_ID = @incidentID\r\n";

			/** OPEN DB **/
			SqlConnection conn = new SqlConnection(connStr);
			conn.Open();
			SqlCommand cmd = new SqlCommand(sql, conn);
			cmd.Parameters.Add(new SqlParameter("incidentID", incidentID));
			SqlDataReader dr = cmd.ExecuteReader();
		
			
			/** START INC01 FILE **/
			string outFile = "c:\\IncOutput\\INC01.txt";
			File.Delete(outFile);
			FileStream fs = new FileStream(outFile, FileMode.CreateNew);
			StreamWriter sw = new StreamWriter(fs);

			/** WRITE HEADER (INC01) **/
			sw.Write(GetHeader("INC01"));
			
			/** BEGIN MASTER INCIDENT **/
			definitionNode = GetDefinitionNode("Response_Master_Incident");
			OutputSection(dr, definitionNode, sw, 1);
			
		
			/** BEGIN COMMENTS **/
			dr.NextResult();
			definitionNode = GetDefinitionNode("Response_Comments");
			int repeatCount = int.Parse(definitionNode.Attributes["Count"].Value);
			OutputSection(dr, definitionNode, sw, repeatCount);

			/** BEGIN TRANSPORTS **/
			dr.NextResult();
			definitionNode = GetDefinitionNode("Response_Transports");
			repeatCount = int.Parse(definitionNode.Attributes["Count"].Value);
			OutputSection(dr, definitionNode, sw, repeatCount);
			
			/** COURTESY FLUSH **/
			sw.Flush();
			
			/** CLOSE FILE **/
			sw.Write(GetChar(CharCodes.ETX));
			sw.Flush();
			sw.Close();
			fs.Close();
			sw.Dispose();
			fs.Dispose();

			/** = = = = = = = = = = = = = = = = = = = = = = = **/
			
			/** START INC02 FILE **/
			outFile = "c:\\IncOutput\\INC02.txt";
			File.Delete(outFile);
			fs = new FileStream(outFile, FileMode.CreateNew);
			sw = new StreamWriter(fs);

			/** WRITE HEADER (INC02) **/
			sw.Write(GetHeader("INC02"));

			/** WRITE AGENCY IDENTIFIER AND INCIDENT NUMBER **/
			//TODO: agency identifier
			sw.Write("??" + GetChar(CharCodes.FS));
			sw.Write(masterIncidentNum + GetChar(CharCodes.FS));
			
			/** BEGIN VEHICLES ASSIGNED **/
			dr.NextResult();
			definitionNode = GetDefinitionNode("Response_Vehicles_Assigned");
			OutputSection(dr, definitionNode, sw, 0);
			
			/** COURTESY FLUSH **/
			sw.Flush();

			/** CLOSE FILE **/
			sw.Write(GetChar(CharCodes.ETX));
			sw.Flush();
			sw.Close();
			fs.Close();
			sw.Dispose();
			fs.Dispose();

			/** CLOSE DATABASE */
			dr.Close();
			dr.Dispose();
			cmd.Dispose();
			conn.Close();
			conn.Dispose();
		}


		/// <summary>
		/// Returns a XMLNode containing the definiton of the specified table as 
		/// specified in the FieldDefinitions.xml file.
		/// </summary>
		/// <param name="p">A string containing the table name for which 
		/// to retrieve the definition.</param>
		/// <returns>A XMLNode containing the definition of the specified
		/// table.</returns>
		private static XmlNode GetDefinitionNode(string p) {
			if (xdoc == null) {
				xdoc = new XmlDocument();
				xdoc.InnerXml = File.ReadAllText("FieldDefinitions.xml");
			}

			return xdoc.DocumentElement.SelectSingleNode(
				"TableDefinition[@Name='"+p+"']"); 
		}


		/// <summary>
		/// Outputs a section of the data stream.
		/// </summary>
		/// <param name="dr">The DataReader, containing the data to output.</param>
		/// <param name="definitionNode">The data definition XMLNode.</param>
		/// <param name="sw">The StreamWriter to write to.</param>
		/// <param name="repeatCount">The number of times to repeat (or fluff). A
		/// value of zero (0) means these records are not fixed length, and should 
		/// be repeated for all results - and not padded.</param>
		private static void OutputSection(SqlDataReader dr, XmlNode defNode, 
			StreamWriter sw, int repeatCount) {
			int i = 0;
			while (dr.Read()) {
				i++;
				
				foreach (XmlNode fieldNode in defNode) {
					// skip comments, etc.
					if (fieldNode.Name != "Field")
						continue;
					string fieldName = fieldNode.Attributes["Name"].Value;
					int fieldLen = int.Parse(fieldNode.Attributes["Length"].Value);

					// PERSONNEL: I have to do this ridiculousness for the personnel
					//   subquery 
					if (fieldName == "Personnel") {
						string personnelFields = GetPersonnel((int)dr["ID"]);
						sw.Write(personnelFields);
						continue;
					}
					
					// store master incident number
					if (fieldName == "Master_Incident_Number") {
						masterIncidentNum = dr[fieldName].ToString();
					}

					string val = FormatValue(dr[fieldName], fieldLen);
					sw.Write(val);
				}
			}

			// For non-fixed-length records, just return. No padding necessary.
			if (repeatCount == 0)
				return;

			// if there were fewer records returned than repeatCount, and these
			// records are fixed-length, we need to add white space to fill 
			// in the rest.
			if (i < repeatCount) {
				// determine the record length
				int recLen = 0;
				foreach (XmlNode fieldNode in defNode) {
					recLen += int.Parse(fieldNode.Attributes["Length"].Value);
				}

				// fluff with spaces for records that weren't written
				int fluffLen = recLen * (repeatCount - i);
				sw.Write("".PadRight(fluffLen, ' '));
			}

		}

		/// <summary>
		/// Returns the top 6 personnel records for the specified Veh_Assigned_ID
		/// separated by a FS
		/// </summary>
		private static string GetPersonnel(int vehAssID) {
			string connStr = Properties.Settings.Default.Connection;
			string sql = "SELECT TOP 6 Personnel_Table_ID " + 
						"FROM Response_Vehicles_Personnel " +
						"WHERE Veh_Assigned_ID  = @vehAssID";

			/** OPEN DB **/
			SqlConnection conn = new SqlConnection(connStr);
			conn.Open();
			SqlCommand cmd = new SqlCommand(sql, conn);
			cmd.Parameters.Add(new SqlParameter("vehAssID", vehAssID));
			SqlDataReader dr = cmd.ExecuteReader();

			string ret = "";
			for (int i = 0; i < 6; i++) {
				if (dr.Read()) {
					ret += dr[0].ToString();
				}
				ret+=GetChar(CharCodes.FS);
			}

			/** CLOSE DATABASE */
			dr.Close();
			dr.Dispose();
			cmd.Dispose();
			conn.Close();
			conn.Dispose();

			return ret;
		}


		/// <summary>
		/// Formats a value, adding padding or truncating values to match 
		/// fieldLen. Also formats dates and converts bools to 1/0. 
		/// </summary>
		/// <param name="val">Object to format.</param>
		/// <param name="fieldLen">Length to pad/truncate. 
		/// If zero (0), appends a FS to the return val.</param>
		/// <returns>A string, formatted and padded or truncated.</returns>
		private static string FormatValue(object val, int fieldLen) {
			string ret = val.ToString();
			
			// DateTime
			if (val is DateTime) {
				DateTime d = (DateTime)val;
				if (fieldLen > 0) {
					ret = d.ToString("MM/dd/yyHH:mm:ss");
				} else {
					ret = d.ToString("MM/dd/yy" + GetChar(CharCodes.FS) +
						"HH:mm:ss" + GetChar(CharCodes.FS));
				}
				return ret;
				
			}

			// Boolean
			if (val is Boolean) {
				ret = ((bool)val)?"1":"0";
				if (fieldLen > 0) {
					ret += GetChar(CharCodes.FS);
				}
				return ret;
			}

			// String
			if (fieldLen > 0) {
				// for fixed width fields, trim or pad them 
				ret = ret.PadRight(fieldLen, ' '); // pad
				if (ret.Length > fieldLen)
					ret = ret.Substring(0, fieldLen); // trim
			} else {
				// non-fixed-width: just append a field separator
				ret = ret + GetChar(CharCodes.FS);
			}
			
			return ret;
		}

		private static string FormatValue(object val) {
			return FormatValue(val, 0);
		}

		static string GetHeader(string msgType) {
			string dateString = FormatValue(DateTime.Now, 16);
			return GetChar(CharCodes.SOH) +
				msgType + GetChar(CharCodes.FS) + // message type
				"1.0" + GetChar(CharCodes.FS) + // message format version
				dateString + GetChar(CharCodes.FS) + // date/time stamp 
				"0" + GetChar(CharCodes.FS) + // supress reply flag
				GetChar(CharCodes.FS) + // group quantity
				GetChar(CharCodes.FS) + // originating id
				GetChar(CharCodes.FS) + // vendor use
				GetChar(CharCodes.FS) + // reserved
				GetChar(CharCodes.FS) + // reserved
				GetChar(CharCodes.STX); // reserved
		}


		/// <summary>
		/// Returns a char corresponding to the specified CharCode
		/// </summary>
		/// <param name="code"></param>
		/// <returns></returns>
		static char GetChar(CharCodes code) {
			return Convert.ToChar((int)code);
		}

		/// <summary>
		/// An enumeration of character codes, and their ASCII decimal value.
		/// </summary>
		enum CharCodes { 
			/// <summary>
			/// Start of Header
			/// </summary>
			SOH = 1,

			/// <summary>
			/// Start of Text
			/// </summary>
			STX = 2, 

			/// <summary>
			/// End of Text
			/// </summary>
			ETX = 3,
 
			/// <summary>
			/// Line Feed
			/// </summary>
			LF = 10, 

			/// <summary>
			/// Carriage Return
			/// </summary>
			CR = 13, 

			/// <summary>
			/// Field Separator
			/// </summary>
			FS = 28
		}
	}
}