<commit_before>/*
    Weave (Web-based Analysis and Visualization Environment)
    Copyright (C) 2008-2011 University of Massachusetts Lowell

    This file is a part of Weave.

    Weave is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License, Version 3,
    as published by the Free Software Foundation.

    Weave is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Weave.  If not, see <http://www.gnu.org/licenses/>.
*/

package weave.application
{
	import flash.display.LoaderInfo;
	import flash.display.StageDisplayState;
	import flash.events.ContextMenuEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.SharedObject;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.system.Capabilities;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	import flash.utils.getQualifiedClassName;
	import flash.utils.getTimer;
	
	import mx.collections.ArrayCollection;
	import mx.containers.VBox;
	import mx.controls.Alert;
	import mx.controls.Button;
	import mx.controls.Image;
	import mx.controls.Text;
	import mx.core.IToolTip;
	import mx.core.UIComponent;
	import mx.effects.Fade;
	import mx.events.EffectEvent;
	import mx.events.FlexEvent;
	import mx.managers.PopUpManager;
	import mx.managers.ToolTipManager;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.utils.URLUtil;
	
	import spark.components.Group;
	
	import weave.Weave;
	import weave.WeaveProperties;
	import weave.api.core.ICallbackCollection;
	import weave.api.core.ILinkableHashMap;
	import weave.api.core.ILinkableObject;
	import weave.api.data.IAttributeColumn;
	import weave.api.data.IDataSource;
	import weave.api.detectLinkableObjectChange;
	import weave.api.getCallbackCollection;
	import weave.api.objectWasDisposed;
	import weave.api.registerDisposableChild;
	import weave.api.reportError;
	import weave.api.ui.IObjectWithSelectableAttributes;
	import weave.api.ui.IVisTool;
	import weave.compiler.StandardLib;
	import weave.core.LinkableBoolean;
	import weave.data.DataSources.WeaveDataSource;
	import weave.data.KeySets.KeySet;
	import weave.editors.SessionHistorySlider;
	import weave.editors.SingleImagePlotterEditor;
	import weave.editors.WeavePropertiesEditor;
	import weave.editors.managers.DataSourceManager;
	import weave.services.LocalAsyncService;
	import weave.services.addAsyncResponder;
	import weave.ui.AddExternalTool;
	import weave.ui.AlertTextBox;
	import weave.ui.AlertTextBoxEvent;
	import weave.ui.AttributeSelectorPanel;
	import weave.ui.CirclePlotterSettings;
	import weave.ui.ColorController;
	import weave.ui.CustomContextMenuManager;
	import weave.ui.CustomToolTipBorder;
	import weave.ui.DraggablePanel;
	import weave.ui.EquationEditor;
	import weave.ui.ErrorLogPanel;
	import weave.ui.ExportSessionStateOptions;
	import weave.ui.NewUserWizard;
	import weave.ui.OICLogoPane;
	import weave.ui.PenTool;
	import weave.ui.PrintPanel;
	import weave.ui.ProbeToolTipEditor;
	import weave.ui.ProbeToolTipWindow;
	import weave.ui.QuickMenuPanel;
	import weave.ui.SelectionManager;
	import weave.ui.SessionStateEditor;
	import weave.ui.SubsetManager;
	import weave.ui.WeaveProgressBar;
	import weave.ui.WizardPanel;
	import weave.ui.annotation.SessionedTextBox;
	import weave.ui.collaboration.CollaborationEditor;
	import weave.ui.collaboration.CollaborationMenuBar;
	import weave.ui.collaboration.CollaborationTool;
	import weave.ui.controlBars.VisTaskbar;
	import weave.ui.controlBars.WeaveMenuBar;
	import weave.ui.controlBars.WeaveMenuItem;
	import weave.utils.ColumnUtils;
	import weave.utils.DebugTimer;
	import weave.utils.VectorUtils;
	import weave.utils.fixErrorMessage;
	import weave.visualization.tools.WeaveAnalyst;

	internal class VisApplication extends VBox implements ILinkableObject
	{
		MXClasses; // Referencing this allows all Flex classes to be dynamically created at runtime.
		
		SessionStateEditor.initialize; // adds keyboard shortcut & upper-left click shortcut

		/**
		 * Constructor.
		 */
		public function VisApplication()
		{
			super();
			registerDisposableChild(Weave.properties, this);

			setStyle("paddingLeft", 0);
			setStyle("paddingRight", 0);
			setStyle("paddingTop", 0);
			setStyle("paddingBottom", 0);
			
			setStyle("marginLeft", 0);
			setStyle("marginRight", 0);
			setStyle("marginTop", 0);
			setStyle("marginBottom", 0);
			
			setStyle("verticalGap", 0);
			setStyle("horizingalGap", 0);
			setStyle('backgroundAlpha', 1);
			
			// make it so the menu bar does not get hidden if the workspace size is too small.
			clipContent = false;
			autoLayout = true;
			
			// no scrolling
			horizontalScrollPolicy = "off";
			verticalScrollPolicy   = "off";
			visDesktop.verticalScrollPolicy   = "off";
			visDesktop.horizontalScrollPolicy = "off";
			
			percentWidth = 100;
			percentHeight = 100;

			callLater(waitForApplicationComplete);
		}

		/**
		 * This needs to be a function because FlashVars can't be fetched while the application is loading.
		 */
		private function waitForApplicationComplete():void
		{
			if (!root)
			{
				callLater(waitForApplicationComplete);
				return;
			}
			
			try {
				loaderInfo['uncaughtErrorEvents'].addEventListener(
					'uncaughtError',
					function(event:Object):void
					{
						var error:Error = event.error;
						// ignore IME error
						if (error.errorID == 2063)
							return;
						
						fixErrorMessage(error)
						reportError(error);
					}
				);
			} catch (e:Error) { }
			
			// resize to parent size each frame because percentWidth,percentHeight doesn't seem reliable when application is nested
			addEventListener(Event.ENTER_FRAME, updateWorkspaceSize);
			
			getCallbackCollection(WeaveAPI.ErrorManager).addGroupedCallback(this, handleError, WeaveAPI.ErrorManager.errors.length > 0);
			WeaveAPI.globalHashMap.childListCallbacks.addGroupedCallback(this, setupWindowMenu);
			Weave.properties.showCopyright.addGroupedCallback(this, toggleMenuBar);
			Weave.properties.enableMenuBar.addGroupedCallback(this, toggleMenuBar);
			Weave.properties.enableCollaborationBar.addGroupedCallback(this, toggleCollaborationMenuBar);
			
			getCallbackCollection(Weave.savedSelectionKeySets).addGroupedCallback(this, setupSelectionsMenu);
			getCallbackCollection(Weave.savedSubsetsKeyFilters).addGroupedCallback(this, setupSubsetsMenu);
			getCallbackCollection(Weave.properties).addGroupedCallback(this, setupVisMenuItems);
			Weave.properties.backgroundColor.addImmediateCallback(this, invalidateDisplayList, true);

			if (JavaScript.available)
			{
				JavaScript.registerMethod('loadFile', loadFile);
				WeaveAPI.initializeJavaScript(_InitializeWeaveData.WeavePathData);
			}

			getFlashVars();
			handleFlashVarPresentation();
			handleFlashVarAllowDomain();
			
			// disable application until it's ready
			enabled = false;
			
			if (getAdminConnectionName())
			{
				// disable interface while connecting to admin console
				var _this:VisApplication = this;
				_this.enabled = false;
				
				var pendingAdminService:LocalAsyncService = new LocalAsyncService(this, false, getAdminConnectionName());
				addAsyncResponder(
					pendingAdminService.invokeAsyncMethod("ping"),
					function(event:ResultEvent, token:Object = null):void
					{
						// when admin console responds, set adminService
						adminService = pendingAdminService;
						saveTimer.addEventListener(TimerEvent.TIMER, saveRecoverPoint);
						saveTimer.start();
						
						_this.enabled = true;
						setupVisMenuItems(); // make sure 'save session state to server' is shown
						downloadConfigFile();
					},
					function(event:FaultEvent = null, token:Object = null):void
					{
						Alert.show(lang("Unable to connect to the Admin Console.\nYou will not be able to save your session state to the server."), lang("Connection error"));
						
						_this.enabled = true;
						setupVisMenuItems();
						downloadConfigFile();
					}
				);
			}
			else
			{
				downloadConfigFile();
			}
		}

		private function handleError():void
		{
			if (Weave.properties.showErrors.value)
				ErrorLogPanel.openErrorLog();
		}
		
		private var _requestedConfigFile:String;
		private var _loadFileCallback:Function;
		/**
		 * Loads a session state file from a URL.
		 * @param url The URL to the session state file (.weave or .xml).
		 * @param callback Either a Function or a String containing a JavaScript function definition. The callback will be invoked when the file loading completes.
		 * @param noCacheHack If set to true, appends "?" followed by a series of numbers to prevent Flash from using a cached version of the file.
		 */
		public function loadFile(url:String, callback:Object = null, noCacheHack:Boolean = false):void
		{
			_requestedConfigFile = url;
			_loadFileCallback = callback as Function;
			if (callback is String)
				_loadFileCallback = function():void { JavaScript.exec(callback + "();"); };
			
			if (noCacheHack)
				url += "?" + (new Date()).getTime(); // prevent flex from using cache
			
			WeaveAPI.URLRequestUtils.getURL(null, new URLRequest(url), handleConfigFileDownloaded, handleConfigFileFault, _requestedConfigFile);
		}
		
		private function downloadConfigFile():void
		{
			_loadFileCallback = null;<commit_msg>loadFile(): Added option to specify url as a URLRequest.<commit_after>/*
    Weave (Web-based Analysis and Visualization Environment)
    Copyright (C) 2008-2011 University of Massachusetts Lowell

    This file is a part of Weave.

    Weave is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License, Version 3,
    as published by the Free Software Foundation.

    Weave is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Weave.  If not, see <http://www.gnu.org/licenses/>.
*/

package weave.application
{
	import flash.display.LoaderInfo;
	import flash.display.StageDisplayState;
	import flash.events.ContextMenuEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.SharedObject;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.system.Capabilities;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	import flash.utils.getQualifiedClassName;
	import flash.utils.getTimer;
	
	import mx.collections.ArrayCollection;
	import mx.containers.VBox;
	import mx.controls.Alert;
	import mx.controls.Button;
	import mx.controls.Image;
	import mx.controls.Text;
	import mx.core.IToolTip;
	import mx.core.UIComponent;
	import mx.effects.Fade;
	import mx.events.EffectEvent;
	import mx.events.FlexEvent;
	import mx.managers.PopUpManager;
	import mx.managers.ToolTipManager;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.utils.URLUtil;
	
	import spark.components.Group;
	
	import weave.Weave;
	import weave.WeaveProperties;
	import weave.api.core.ICallbackCollection;
	import weave.api.core.ILinkableHashMap;
	import weave.api.core.ILinkableObject;
	import weave.api.data.IAttributeColumn;
	import weave.api.data.IDataSource;
	import weave.api.detectLinkableObjectChange;
	import weave.api.getCallbackCollection;
	import weave.api.objectWasDisposed;
	import weave.api.registerDisposableChild;
	import weave.api.reportError;
	import weave.api.ui.IObjectWithSelectableAttributes;
	import weave.api.ui.IVisTool;
	import weave.compiler.StandardLib;
	import weave.core.LinkableBoolean;
	import weave.data.DataSources.WeaveDataSource;
	import weave.data.KeySets.KeySet;
	import weave.editors.SessionHistorySlider;
	import weave.editors.SingleImagePlotterEditor;
	import weave.editors.WeavePropertiesEditor;
	import weave.editors.managers.DataSourceManager;
	import weave.services.LocalAsyncService;
	import weave.services.addAsyncResponder;
	import weave.ui.AddExternalTool;
	import weave.ui.AlertTextBox;
	import weave.ui.AlertTextBoxEvent;
	import weave.ui.AttributeSelectorPanel;
	import weave.ui.CirclePlotterSettings;
	import weave.ui.ColorController;
	import weave.ui.CustomContextMenuManager;
	import weave.ui.CustomToolTipBorder;
	import weave.ui.DraggablePanel;
	import weave.ui.EquationEditor;
	import weave.ui.ErrorLogPanel;
	import weave.ui.ExportSessionStateOptions;
	import weave.ui.NewUserWizard;
	import weave.ui.OICLogoPane;
	import weave.ui.PenTool;
	import weave.ui.PrintPanel;
	import weave.ui.ProbeToolTipEditor;
	import weave.ui.ProbeToolTipWindow;
	import weave.ui.QuickMenuPanel;
	import weave.ui.SelectionManager;
	import weave.ui.SessionStateEditor;
	import weave.ui.SubsetManager;
	import weave.ui.WeaveProgressBar;
	import weave.ui.WizardPanel;
	import weave.ui.annotation.SessionedTextBox;
	import weave.ui.collaboration.CollaborationEditor;
	import weave.ui.collaboration.CollaborationMenuBar;
	import weave.ui.collaboration.CollaborationTool;
	import weave.ui.controlBars.VisTaskbar;
	import weave.ui.controlBars.WeaveMenuBar;
	import weave.ui.controlBars.WeaveMenuItem;
	import weave.utils.ColumnUtils;
	import weave.utils.DebugTimer;
	import weave.utils.VectorUtils;
	import weave.utils.fixErrorMessage;
	import weave.visualization.tools.WeaveAnalyst;

	internal class VisApplication extends VBox implements ILinkableObject
	{
		MXClasses; // Referencing this allows all Flex classes to be dynamically created at runtime.
		
		SessionStateEditor.initialize; // adds keyboard shortcut & upper-left click shortcut

		/**
		 * Constructor.
		 */
		public function VisApplication()
		{
			super();
			registerDisposableChild(Weave.properties, this);

			setStyle("paddingLeft", 0);
			setStyle("paddingRight", 0);
			setStyle("paddingTop", 0);
			setStyle("paddingBottom", 0);
			
			setStyle("marginLeft", 0);
			setStyle("marginRight", 0);
			setStyle("marginTop", 0);
			setStyle("marginBottom", 0);
			
			setStyle("verticalGap", 0);
			setStyle("horizingalGap", 0);
			setStyle('backgroundAlpha', 1);
			
			// make it so the menu bar does not get hidden if the workspace size is too small.
			clipContent = false;
			autoLayout = true;
			
			// no scrolling
			horizontalScrollPolicy = "off";
			verticalScrollPolicy   = "off";
			visDesktop.verticalScrollPolicy   = "off";
			visDesktop.horizontalScrollPolicy = "off";
			
			percentWidth = 100;
			percentHeight = 100;

			callLater(waitForApplicationComplete);
		}

		/**
		 * This needs to be a function because FlashVars can't be fetched while the application is loading.
		 */
		private function waitForApplicationComplete():void
		{
			if (!root)
			{
				callLater(waitForApplicationComplete);
				return;
			}
			
			try {
				loaderInfo['uncaughtErrorEvents'].addEventListener(
					'uncaughtError',
					function(event:Object):void
					{
						var error:Error = event.error;
						// ignore IME error
						if (error.errorID == 2063)
							return;
						
						fixErrorMessage(error)
						reportError(error);
					}
				);
			} catch (e:Error) { }
			
			// resize to parent size each frame because percentWidth,percentHeight doesn't seem reliable when application is nested
			addEventListener(Event.ENTER_FRAME, updateWorkspaceSize);
			
			getCallbackCollection(WeaveAPI.ErrorManager).addGroupedCallback(this, handleError, WeaveAPI.ErrorManager.errors.length > 0);
			WeaveAPI.globalHashMap.childListCallbacks.addGroupedCallback(this, setupWindowMenu);
			Weave.properties.showCopyright.addGroupedCallback(this, toggleMenuBar);
			Weave.properties.enableMenuBar.addGroupedCallback(this, toggleMenuBar);
			Weave.properties.enableCollaborationBar.addGroupedCallback(this, toggleCollaborationMenuBar);
			
			getCallbackCollection(Weave.savedSelectionKeySets).addGroupedCallback(this, setupSelectionsMenu);
			getCallbackCollection(Weave.savedSubsetsKeyFilters).addGroupedCallback(this, setupSubsetsMenu);
			getCallbackCollection(Weave.properties).addGroupedCallback(this, setupVisMenuItems);
			Weave.properties.backgroundColor.addImmediateCallback(this, invalidateDisplayList, true);

			if (JavaScript.available)
			{
				JavaScript.registerMethod('loadFile', loadFile);
				WeaveAPI.initializeJavaScript(_InitializeWeaveData.WeavePathData);
			}

			getFlashVars();
			handleFlashVarPresentation();
			handleFlashVarAllowDomain();
			
			// disable application until it's ready
			enabled = false;
			
			if (getAdminConnectionName())
			{
				// disable interface while connecting to admin console
				var _this:VisApplication = this;
				_this.enabled = false;
				
				var pendingAdminService:LocalAsyncService = new LocalAsyncService(this, false, getAdminConnectionName());
				addAsyncResponder(
					pendingAdminService.invokeAsyncMethod("ping"),
					function(event:ResultEvent, token:Object = null):void
					{
						// when admin console responds, set adminService
						adminService = pendingAdminService;
						saveTimer.addEventListener(TimerEvent.TIMER, saveRecoverPoint);
						saveTimer.start();
						
						_this.enabled = true;
						setupVisMenuItems(); // make sure 'save session state to server' is shown
						downloadConfigFile();
					},
					function(event:FaultEvent = null, token:Object = null):void
					{
						Alert.show(lang("Unable to connect to the Admin Console.\nYou will not be able to save your session state to the server."), lang("Connection error"));
						
						_this.enabled = true;
						setupVisMenuItems();
						downloadConfigFile();
					}
				);
			}
			else
			{
				downloadConfigFile();
			}
		}

		private function handleError():void
		{
			if (Weave.properties.showErrors.value)
				ErrorLogPanel.openErrorLog();
		}
		
		private var _requestedConfigFile:String;
		private var _loadFileCallback:Function;
		/**
		 * Loads a session state file from a URL.
		 * @param url The URL to the session state file (.weave or .xml) specified as a String or a URLRequest.
		 * @param callback Either a Function or a String containing a JavaScript function definition. The callback will be invoked when the file loading completes.
		 * @param noCacheHack If set to true, appends "?" followed by a series of numbers to prevent Flash from using a cached version of the file.  Only works when url is given as a String.
		 */
		public function loadFile(url:Object, callback:Object = null, noCacheHack:Boolean = false):void
		{
			if (noCacheHack && url is String)
				url = String(url) + "?" + (new Date()).getTime(); // prevent flex from using cache
			
			var request:URLRequest = url as URLRequest || new URLRequest(String(url));
			_requestedConfigFile = request.url;
			_loadFileCallback = callback as Function;
			if (callback is String)
				_loadFileCallback = function():void { JavaScript.exec(callback + "();"); };
			
			WeaveAPI.URLRequestUtils.getURL(null, request, handleConfigFileDownloaded, handleConfigFileFault, _requestedConfigFile);
		}
		
		private function downloadConfigFile():void
		{
			_loadFileCallback = null;
{'fraction_non_alphanumeric': 0.08920305896558664, 'fraction_numerical': 0.0031193399074260415, 'mean_word_length': 4.32609860664523, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '126433', 'n_tokens_mistral': 6745, 'n_tokens_neox': 5820, 'n_words': 1413}