digraph {
	#ratio = 0.75;

	compound = true;
	newrank = true;
	#splines=line
	edge [splines = "curved"];
	node [fontname = "Courier"];
	edge [fontname = "Courier"];
	#subgraph [fontname = "Courier"];
	clusterrank = "local";
	
	# Initialization
	{
		node [shape = "plaintext"];

		INIT;
	}
	
	NO_CONTROLLER;
	FIRST_READ;

	INIT -> NO_CONTROLLER;
	NO_CONTROLLER -> FIRST_READ [label = "Supported controller plugged-in"];
	FIRST_READ -> FACTORY_RESET_WAIT_1 [label = "SELECT pressed"];
	FIRST_READ -> MODE_JOYSTICK [label = "SELECT not pressed"]

	# Main Mode Transitions
	subgraph "cluster_main" {
		label = "Main Modes";
		fontname = "Courier-bold";
		fontsize = "20pt";
		style = "filled";

		{
			rank="same";
			node [style = "filled"];

			MODE_MOUSE;
			MODE_JOYSTICK;
			MODE_CD32;
		}

		MODE_JOYSTICK -> MODE_MOUSE [label = "Right Analog Stick Moved"];
		MODE_CD32 -> MODE_MOUSE [label = "Right Analog Stick Moved"];
		MODE_MOUSE -> MODE_JOYSTICK [label = "D-Pad Button Pressed"];
		MODE_JOYSTICK -> MODE_CD32 [label = "Pin 5 Set LOW"];
	}

	MODE_CD32 -> MODE_JOYSTICK_TEMP [label = "Pin 5 Set HIGH"];
	MODE_JOYSTICK_TEMP -> MODE_CD32 [label = "Pin 5 Set LOW"];
	MODE_JOYSTICK_TEMP -> MODE_JOYSTICK [label = "<TIMEOUT_CD32_MODE> elapsed"];

	# This actually represents a transitions valid for all nodes in the cluster
	MODE_JOYSTICK -> NO_CONTROLLER [label = "Controller Read Error", ltail = cluster_main];
	
	subgraph "cluster_progswitch" {
		label = "Select Mapping/Switch to Programming Mode";
		fontname = "Courier-bold";
		fontsize = "20pt";
		
		# States for entering Programming Mode
		SELECT_HELD;
		SELECT_AND_BTN_HELD;
		ENABLE_MAPPING;

		SELECT_HELD -> SELECT_AND_BTN_HELD [label = "X/O/^/[]/R1/R2/L1/L2/Start Pressed"]
		SELECT_AND_BTN_HELD -> ENABLE_MAPPING [label = "X/O/^/[]/R1/R2/L1/L2/Start Released"]
		SELECT_AND_BTN_HELD -> ENABLE_MAPPING [label = "SELECT Released"]
	}

	MODE_JOYSTICK -> SELECT_HELD [label = "SELECT Pressed"]
	SELECT_HELD -> MODE_JOYSTICK [label = "SELECT Released"]
	ENABLE_MAPPING -> MODE_JOYSTICK [label = "Mapping enabled"]
	SELECT_AND_BTN_HELD -> WAIT_SELECT_RELEASE [label = "<TIMEOUT_PROGRAMMING_MODE> Elapsed"]

	# Again, valid for all nodes in the cluster
	SELECT_HELD -> NO_CONTROLLER [label = "Controller Read Error", ltail = cluster_progswitch];

	subgraph "cluster_progmode" {
		label = "Programming Mode";
		fontname = "Courier-bold";
		fontsize = "20pt";
		
		# Programming Mode States
		WAIT_SELECT_RELEASE;
		WAIT_BUTTON_PRESS;
		WAIT_BUTTON_RELEASE;
		WAIT_COMBO_PRESS;
		WAIT_COMBO_RELEASE;
		WAIT_SELECT_RELEASE_FOR_EXIT;

		WAIT_SELECT_RELEASE -> WAIT_BUTTON_PRESS [label = "SELECT Released"]
		WAIT_BUTTON_PRESS -> WAIT_SELECT_RELEASE_FOR_EXIT [label = "SELECT Pressed"]
		WAIT_BUTTON_PRESS -> WAIT_BUTTON_RELEASE [label = "Single Mappable Button Pressed"]
		WAIT_BUTTON_PRESS -> WAIT_BUTTON_PRESS [label = "Several Buttons or Unmappable Button Pressed"]
		WAIT_BUTTON_RELEASE -> WAIT_COMBO_PRESS [label = "Button Released"]
		WAIT_COMBO_PRESS -> WAIT_COMBO_RELEASE [label = "Combo Pressed"]
		WAIT_COMBO_RELEASE -> WAIT_BUTTON_PRESS [label = "Combo Released"]
	}

	WAIT_SELECT_RELEASE_FOR_EXIT -> MODE_JOYSTICK [label = "SELECT Released"]

	# Guess what??? Valid for all nodes in the cluster
	WAIT_SELECT_RELEASE -> NO_CONTROLLER [label = "Controller Read Error", ltail = cluster_progmode];
	
	subgraph "cluster_reset" {
		label = "Factory Reset";
		fontname = "Courier-bold";
		fontsize = "20pt";
		
		FACTORY_RESET_WAIT_1;
		FACTORY_RESET_WAIT_2;
		FACTORY_RESET_PERFORM;
		
		FACTORY_RESET_WAIT_1 -> FACTORY_RESET_WAIT_2 [label = "2 Seconds Elapsed"];
		FACTORY_RESET_WAIT_2 -> FACTORY_RESET_PERFORM [label = "2 Seconds Elapsed"];
	}
	
	FACTORY_RESET_PERFORM -> MODE_JOYSTICK;
	
	# Valid for all nodes in the cluster
	FACTORY_RESET_WAIT_1 -> MODE_JOYSTICK [label = "SELECT Released", ltail = cluster_reset];
}
