public void init(){
		__addMultiple = false;
		__removeMultiple = false;
		
		__outputSelection = null;
		
		initPhaseTypes();
		initSections();
		
		getPhaseScrollLimits();
		
		__initialized = true;
	}
	private void handleMouse(){
		if(Event.current.type == EventType.MouseUp){
			__dragSelection = null;
			__outputSelection = null;
		}
	}
	private void handlePhaseInputClicked(int phaseId){
		
		DialogueEditorDialogueObject dialogue = DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId];
		if(__outputSelection != null){
			if(__outputSelection.isStart){
				dialogue.startPage = phaseId;
			}else{
				DialogueEditorPhaseObject selectedPhase = dialogue.phases[__outputSelection.phaseId];
				if(phaseId != selectedPhase.id) selectedPhase.outs[__outputSelection.outputIndex] = phaseId;
			}
		}
		__outputSelection = null;
	}
	// CANVAS / DIALOGUE EDITOR
	
	private void drawCanvas(){
		
		__canvasSection.bodyRect = new Rect(250 + 5 + 5, 5, Screen.width - (250 + 5 + 6 + 5), Screen.height - 20 - 5*2);
		__canvasSection.draw();
		
		if(DialogueEditorDataManager.data.count < 0 || DialogueEditorDataManager.data.currentDialogueId >= DialogueEditorDataManager.data.count) return;
		
		// Dialogue Name
		Rect nameRect = new Rect(__canvasSection.toolbarRect.x+5, __canvasSection.toolbarRect.y + 6, 200, __canvasSection.toolbarRect.height - 12);
		Rect nameShadowRect = new Rect(nameRect.x - 1, nameRect.y - 1, nameRect.width + 2, nameRect.height + 2);
		GUIStyle nameTextStyle = new GUIStyle(GUI.skin.GetStyle("textfield"));
		nameTextStyle.fontSize = 22;
		GUI.color = GUI.contentColor;
		if(isPro){
			GUI.Box(nameShadowRect, string.Empty);
		}else{
			GUI.Box(nameShadowRect, string.Empty, DialogueEditorGUI.gui.GetStyle("box_inset"));
		}
		if(DialogueEditorDataManager.data.currentDialogueId < DialogueEditorDataManager.data.count && DialogueEditorDataManager.data.currentDialogueId >= 0){
			DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].name = GUI.TextField(nameRect, DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].name, nameTextStyle);
			GUI.color = new Color(1,1,1,0.25f);
			if(DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].name == "") GUI.Label(nameRect, "Dialogue Name", nameTextStyle);
		}
		
		
		
		GUI.color = GUI.contentColor;
		
		// TOOLBAR BUTTONS
		int numberOfTools = System.Enum.GetValues(typeof(DialogueEditorPhaseTypes)).Length - 1;
		int buttonSize = 30;
		Rect[] toolButtonRects = new Rect[numberOfTools];
		Rect toolbarInnerRect = new Rect(__canvasSection.toolbarRect.x + 200 + 15, __canvasSection.toolbarRect.y + 5, 5 + (buttonSize*numberOfTools) + 5, __canvasSection.toolbarRect.height - 10);
		for(int t=0; t<numberOfTools; t+=1){
			GUIStyle toolStyle;
			if(t == 0){
				toolStyle = DialogueEditorGUI.gui.GetStyle("toolbar_left");
			}else if(t == numberOfTools - 1){
				toolStyle = DialogueEditorGUI.gui.GetStyle("toolbar_right");
			}else{
				toolStyle = DialogueEditorGUI.gui.GetStyle("toolbar_center");
			}
			
			toolButtonRects[t] = new Rect(toolbarInnerRect.x + buttonSize*t, toolbarInnerRect.y, buttonSize, buttonSize);
			if(GUI.Button(toolButtonRects[t], (isPro)? __phaseTypes[t].iconDark : __phaseTypes[t].iconLight, toolStyle)){
				Vector2 newPhasePosition = Vector2.zero;
				//newPhasePosition.x = __canvasSection.scrollRect.width * 0.5f + __canvasSection.scrollPosition.x - 100;
				//newPhasePosition.y = __canvasSection.scrollRect.height * 0.5f + __canvasSection.scrollPosition.y - 100;
				newPhasePosition.x = DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].scrollPosition.x + 20;
				newPhasePosition.y = DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].scrollPosition.y + 20;
				DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].addPhase(__phaseTypes[t].type, newPhasePosition);
			}
			
			
			if(toolButtonRects[t].Contains(Event.current.mousePosition)){
				string toolName = __phaseTypes[t].name;
				string toolInfo = __phaseTypes[t].info;
				setToolInfo(toolName, toolInfo);
			}
		}
		
		
		
		//TOOLTIP
		Rect toolInfoBg = new Rect(toolbarInnerRect.x + toolbarInnerRect.width, toolbarInnerRect.y, 300, toolbarInnerRect.height);
		if(isPro){
			GUI.color = Color.black;
			DialogueEditorGUI.drawShadowedRect(toolInfoBg);
		}else{
			GUI.Box(toolInfoBg, string.Empty, DialogueEditorGUI.gui.GetStyle("box_outset"));
		}
		GUI.Label(new Rect(toolInfoBg.x + 2, toolInfoBg.y + 2, toolInfoBg.width - 4, toolInfoBg.height - 4), __toolInfoName, EditorStyles.boldLabel);
		GUIStyle tooltipInfoStyle = new GUIStyle(EditorStyles.miniLabel);
		tooltipInfoStyle.alignment = TextAnchor.UpperLeft;
		GUI.Label(new Rect(toolInfoBg.x + 2, toolInfoBg.y + 15, toolInfoBg.width - 4, toolInfoBg.height - 15), __toolInfoDescription, tooltipInfoStyle);
		


		// LOAD BUTTON
		/*
		GUI.color = DialogueEditorStyles.COLOR_BUTTON_BLUE;
		if(GUI.Button(new Rect(__canvasSection.toolbarRect.x +__canvasSection.toolbarRect.width - (100 + 10), __canvasSection.toolbarRect.y + 5, 50, __canvasSection.toolbarRect.height - 10), "Load")){
			DialogueEditorDataManager.debugLoad();
		}
		GUI.color = GUI.contentColor;
		*/

		// SAVE BUTTON
		//GUI.color = DialogueEditorStyles.COLOR_BUTTON_GREEN;
		if(GUI.Button(new Rect(__canvasSection.toolbarRect.x +__canvasSection.toolbarRect.width - (50 + 5), __canvasSection.toolbarRect.y + 5, 50, __canvasSection.toolbarRect.height - 10), "Save")){
			DialogueEditorDataManager.save();
		}
		//GUI.color = GUI.contentColor;

		if(GUI.Button(new Rect(__canvasSection.toolbarRect.x +__canvasSection.toolbarRect.width - (75 + 10), __canvasSection.toolbarRect.y + 5, 25, __canvasSection.toolbarRect.height - 10), "?")){
			//DialogueEditorDataManager.debugLoad();
		}
		
		
		// CANVAS =========================== SCROLL BOX
		Vector2 newScrollSize = Vector2.zero;
		newScrollSize.x = (__scrollLimits.x > __canvasSection.scrollRect.width) ? __scrollLimits.x : __canvasSection.scrollRect.width - 15;
		newScrollSize.y = (__scrollLimits.y > __canvasSection.scrollRect.height) ? __scrollLimits.y : __canvasSection.scrollRect.height - 15;
		//Vector2 canvasScrollPosition = DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].scrollPosition;
		if(!isPro){
			GUI.Box(DialogueEditorGUI.getOutlineRect(__canvasSection.scrollRect,1), string.Empty, DialogueEditorGUI.gui.GetStyle("box_inset"));
		}
		if(DialogueEditorDataManager.data.dialogues.Count < 1){
			GUI.BeginScrollView(__canvasSection.scrollRect, getScrollPosition(), new Rect(0,0,newScrollSize.x, newScrollSize.y),true, true);
			GUI.EndScrollView();
			return;
		}
		if(__panning){
			GUI.BeginScrollView(__canvasSection.scrollRect, getScrollPosition(), new Rect(0,0,newScrollSize.x, newScrollSize.y),true, true);
		}else{
			DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].scrollPosition = GUI.BeginScrollView(__canvasSection.scrollRect, getScrollPosition(), new Rect(0,0,newScrollSize.x, newScrollSize.y),true, true);
		}
		
		GUI.color = (EditorGUIUtility.isProSkin) ? new Color(1,1,1,0.25f) : new Color(1,1,1,0.1f) ;
		GUI.DrawTextureWithTexCoords(
			new Rect(0,0,newScrollSize.x, newScrollSize.y),
			DialogueEditorGUI.scrollboxBgTexture,
			new Rect(0, 0, newScrollSize.x / DialogueEditorGUI.scrollboxBgTexture.width, newScrollSize.y / DialogueEditorGUI.scrollboxBgTexture.height)
		);
		GUI.color = GUI.contentColor;
		
		// No-Entries Hint
		if(DialogueEditorDataManager.data.count > 0 && DialogueEditorDataManager.data.currentDialogueId < DialogueEditorDataManager.data.count && DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].phases.Count <= 0){
			Rect warningBox = new Rect(200 + 15, 10, __selectorSection.scrollRect.width - 40 - 15, 70);
			GUI.color = Color.black;
			GUI.Box(new Rect(warningBox.x - 1, warningBox.y - 1, warningBox.width + 2, warningBox.height+2),string.Empty);
			GUI.color = GUI.contentColor;
			GUI.Box(warningBox, string.Empty);
			GUIStyle style = new GUIStyle(EditorStyles.miniLabel);
			style.wordWrap = true;
			style.alignment = TextAnchor.MiddleCenter;
			GUI.Label(warningBox, "Press 'Add' to begin creating dialogue objects!", style);
		}
		
		//Draw Connections
		drawConnections();
		
		// Handle Middle Mouse Drag for Panning
		handleCanvasMiddleMouseDrag();
		
		// START BOX
		Rect startRect = new Rect(10, 10, 150, 70);
		GUI.Box(startRect, string.Empty, DialogueEditorGUI.gui.GetStyle("box_opaque"));
		Rect startLabelRect = new Rect(startRect.x + 4, startRect.y + 3, startRect.width, 20);
		GUI.Label(startLabelRect, "Start Page");
		string startConnectorType = (DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].startPage != null) ? "connector_full" : "connector_empty" ;
		Rect startOutputButtonRect = new Rect(startRect.x + startRect.width - 19,startRect.y + 3,16,16);
		if(Event.current.type == EventType.MouseDown && startOutputButtonRect.Contains(Event.current.mousePosition)){
			if (Event.current.button == 0){
				DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].startPage = null;
				__outputSelection = new DialogueEditorSelectionObject(true);
			}else if (Event.current.button == 1){
				DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].startPage = null;
				if(__outputSelection != null && __outputSelection.isStart){
					__outputSelection = null;
				}
			}
				
			
		}
		GUI.Button(startOutputButtonRect, string.Empty, DialogueEditorGUI.gui.GetStyle(startConnectorType));
		
		// Local Variables
		GUI.color = new Color(1,1,1,0.5f);
		Rect countLabelsRect = new Rect(startLabelRect.x, startLabelRect.y + 18, startLabelRect.width, 22);
		GUI.Label(new Rect(countLabelsRect.x, countLabelsRect.y, countLabelsRect.width, countLabelsRect.height), "Local Booleans:	" + DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].booleans.variables.Count);
		GUI.Label(new Rect(countLabelsRect.x, countLabelsRect.y + 15, countLabelsRect.width, countLabelsRect.height), "Local Floats:		" + DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].floats.variables.Count);
		GUI.Label(new Rect(countLabelsRect.x, countLabelsRect.y + 30, countLabelsRect.width, countLabelsRect.height), "Local Strings:		" + DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].strings.variables.Count);
		GUI.color = GUI.contentColor;
		
		// CANVAS CONTENTS
		// =-=-=-=-=-=-=-=-=-=-=-=-=-=- CHANGE THESE FUCKERS
		if(DialogueEditorDataManager.data.count > 0 && DialogueEditorDataManager.data.currentDialogueId >= 0 && DialogueEditorDataManager.data.currentDialogueId < DialogueEditorDataManager.data.count && DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].phases.Count > 0){
			for(int i = 0; i < DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].phases.Count; i+=1){
				DialogueEditorPhaseObject phase = DialogueEditorDataManager.data.dialogues[DialogueEditorDataManager.data.currentDialogueId].phases[i];
				
				switch(phase.type){
					
					case DialogueEditorPhaseTypes.TextPhase:
						drawTextPhase(phase);
					break;
					
					case DialogueEditorPhaseTypes.BranchedTextPhase:
						drawBranchedTextPhase(phase);
					break;
					
					/*
					case DialogueEditorPhaseTypes.AsyncPhase:
						drawAsyncPhase(phase);
					break;
					*/
					
					case DialogueEditorPhaseTypes.WaitPhase:
						drawWaitPhase(phase);
					break;
					
					case DialogueEditorPhaseTypes.SetVariablePhase:
						drawSetVariablePhase(phase);
					break;
					
					case DialogueEditorPhaseTypes.ConditionalPhase:
						drawConditionalPhase(phase);
					break;
					
					case DialogueEditorPhaseTypes.SendMessagePhase:
						drawSendMessagePhase(phase);
					break;
					
					case DialogueEditorPhaseTypes.EndPhase:
						drawEndPhase(phase);
					break;
					
					case DialogueEditorPhaseTypes.EmptyPhase:
						Debug.LogWarning("Dialogue:"+DialogueEditorDataManager.data.currentDialogueId+", Page: "+i+" is an EmptyPhase. Something went wrong.");
					break;
				}
			}
		}
		
		// Handle Dragging
		handleDragging();
		
		// Handle Clicks
		handleMouse();
		
		// Canvas debug
		drawCanvasDebug();
		
		GUI.EndScrollView();
		
		
		
		// Scroll bar fill
		GUI.color = Color.black;
		Rect fillRect = new Rect(__canvasSection.scrollRect.x + __canvasSection.scrollRect.width - 15, __canvasSection.scrollRect.y + __canvasSection.scrollRect.height - 15, 16, 16);
		GUI.Box(fillRect, string.Empty);
		GUI.Box(fillRect, string.Empty);
		GUI.Box(fillRect, string.Empty);
		GUI.Box(fillRect, string.Empty);
		
		GUI.color = GUI.contentColor;
		
		drawTooltip();
	}
	private void drawOutputConnector(DialogueEditorPhaseObject phase, Vector2 position, int outputIndex){
		Rect outputButtonRect = new Rect(position.x, position.y, 16, 16);
		string outputButtonType = (phase.outs[outputIndex] != null) ? "connector_full" : "connector_empty" ;
		if(Event.current.type == EventType.MouseDown && outputButtonRect.Contains(Event.current.mousePosition)){
			if (Event.current.button == 0){
				phase.outs[outputIndex] = null;
				__outputSelection = new DialogueEditorSelectionObject(phase.id, outputIndex	);
			}else if (Event.current.button == 1){
				phase.outs[outputIndex] = null;
				if(__outputSelection != null && __outputSelection.phaseId == phase.id && __outputSelection.outputIndex == outputIndex){
					__outputSelection = null;
				}
			}
				
			
		}
		GUI.Button(outputButtonRect, string.Empty, DialogueEditorGUI.gui.GetStyle(outputButtonType));
	}