public void StartDownload(Version resource, Common.Work.Master.JobType jobType)
        {
            if (FindTreeViewItem(resource) != null)
                throw new ArgumentException("The resource already exists.");

            State state;
            TreeViewItem tvi;

            tvi = new TreeViewItem();

            state = new State(resource);
            state.UpdateDirection(false, true);
            state.UpdateEvent(false, false, false, true, false, false, false, false);
            state.UpdateResourceStatus(false, true, false, true, false);

            tvi.Tag = state;
            tvi.Selected += new RoutedEventHandler(TreeViewItem_Selected);

            TreeViewItemProps.SetGuid(tvi, resource.MetaAsset.Guid.ToString("N"));
            TreeViewItemProps.SetIsCanceled(tvi, false);
            TreeViewItemProps.SetIsLoading(tvi, true);
            TreeViewItemProps.SetPercentComplete(tvi, 0);
            UpdateStatus(tvi, "Downloading resource.");

            state.JobType = jobType;

            if (resource.MetaAsset != null && !string.IsNullOrEmpty(resource.MetaAsset.Title))
                tvi.Header = resource.MetaAsset.Title;
            else
                tvi.Header = resource.Guid;

            AddContextMenu(tvi);

            ResourceTree.Items.Add(tvi);

            // Add twice because we need to ignore both the meta and data assets
            _ignoreFileChangesForGuids.Add(resource.Guid);
            _ignoreFileChangesForGuids.Add(resource.Guid);

            SetResourceTreeSelectedIndex(-1);
        }
        /// <summary>
        /// Adds a resource that exists on the local filesystem as a new node on the tree.
        /// </summary>
        /// <param name="resource">The resource.</param>
        public void AddNewExistingLocalResource(Version resource)
        {
            if (FindTreeViewItem(resource) != null)
                throw new ArgumentException("The resource already exists.");

            State state;
            TreeViewItem tvi;

            tvi = new TreeViewItem();
            state = new State(resource);

            tvi.Tag = state;
            tvi.Selected += new RoutedEventHandler(TreeViewItem_Selected);

            TreeViewItemProps.SetGuid(tvi, resource.MetaAsset.Guid.ToString("N"));
            TreeViewItemProps.SetIsCanceled(tvi, false);
            TreeViewItemProps.SetIsLoading(tvi, false);
            TreeViewItemProps.SetPercentComplete(tvi, 0);
            UpdateStatus(tvi, "Resource needs saved to server.");

            state.UpdateDirection(false, false);
            state.UpdateEvent(true, false, false, false, true, false, false, false);
            state.UpdateResourceStatus(true, false, false, false, true);

            tvi.Background = _needUpdatedBrush;

            if (resource.MetaAsset != null && !string.IsNullOrEmpty(resource.MetaAsset.Title))
                tvi.Header = resource.MetaAsset.Title;
            else
                tvi.Header = resource.Guid;


            AddContextMenu(tvi);

            ResourceTree.Items.Add(tvi);

            SetResourceTreeSelectedIndex(-1);
        }
        public void FinishStatusCheck(Common.Work.JobResult result, string fileMd5)
        {
            TreeViewItem tvi;
            State state;

            if ((tvi = FindTreeViewItem(result.Resource)) == null)
            {
                // Item does not exist in the tree, it needs added if the job was successful
                if (result.Job.IsCancelled)
                {
                    MessageBox.Show("Actions on resource " + result.Resource.Guid.ToString("N") + " were cancelled by the user.");
                }
                else if (result.Job.IsError)
                {
                    MessageBox.Show("An error occurred while trying to check the status of the resource " + result.Resource.Guid.ToString("N") + ".");
                }
                else if (result.Job.IsTimeout)
                {
                    MessageBox.Show("Actions on resource " + result.Resource.Guid.ToString("N") + " timed out.");
                }
                else if (result.Job.IsFinished)
                {
                    tvi = new TreeViewItem();
                    state = new State(result.InputArgs.Resource);

                    tvi.Tag = state;
                    tvi.Selected += new RoutedEventHandler(TreeViewItem_Selected);

                    TreeViewItemProps.SetGuid(tvi, result.Resource.Guid.ToString("N"));
                    TreeViewItemProps.SetIsCanceled(tvi, false);
                    TreeViewItemProps.SetIsLoading(tvi, false);
                    TreeViewItemProps.SetPercentComplete(tvi, 0);

                    state.UpdateDirection(false, false);
                    state.UpdateEvent(false, false, false, false, true, false, false, false);
                    if (string.IsNullOrEmpty(result.Resource.MetaAsset.Md5)
                        || result.InputArgs.Resource.MetaAsset.Md5 != fileMd5)
                    {
                        state.UpdateResourceStatus(true, false, false, true, true);
                        UpdateStatus(tvi, "File needs saved to server.");
                        tvi.Background = _needUpdatedBrush;
                    }
                    else
                    {
                        state.UpdateResourceStatus(false, false, true, true, true);
                        UpdateStatus(tvi, "Loaded.");
                        tvi.Background = _normalBrush;
                    }

                    if (result.InputArgs.Resource.MetaAsset != null &&
                        !string.IsNullOrEmpty(result.InputArgs.Resource.MetaAsset.Title))
                        tvi.Header = result.InputArgs.Resource.MetaAsset.Title;
                    else
                        tvi.Header = result.InputArgs.Resource.Guid;

                    AddContextMenu(tvi);

                    ResourceTree.Items.Add(tvi);
                }
                else
                {
                    throw new Exception("Unhandled event");
                }
            }
            else
            {
                // Item does exist in the tree, we just need to update
                state = (State)tvi.Tag;
                TreeViewItemProps.SetIsLoading(tvi, false);
                TreeViewItemProps.SetPercentComplete(tvi, 0);
                state.UpdateDirection(false, false);

                if (result.Job.IsCancelled)
                {
                    TreeViewItemProps.SetIsCanceled(tvi, true);
                    UpdateStatus(tvi, "Status check canceled by user.");
                    state.UpdateEvent(false, false, false, false, true, true, false, false);
                    tvi.Background = _errorBrush;
                }
                else if (result.Job.IsError)
                {
                    TreeViewItemProps.SetIsCanceled(tvi, true);
                    UpdateStatus(tvi, "Error: failed status check.");
                    state.UpdateEvent(false, false, false, false, true, false, false, true);
                    tvi.Background = _errorBrush;
                }
                else if (result.Job.IsTimeout)
                {
                    TreeViewItemProps.SetIsCanceled(tvi, true);
                    UpdateStatus(tvi, "Error: timeout occurred performing status check.");
                    state.UpdateEvent(false, false, false, false, true, false, true, false);
                    tvi.Background = _errorBrush;
                }
                else if (result.Job.IsFinished)
                {
                    TreeViewItemProps.SetIsCanceled(tvi, true);
                    
                    state.UpdateEvent(false, false, false, false, true, false, false, false);
                    if (string.IsNullOrEmpty(result.Resource.MetaAsset.Md5)
                        || result.Resource.MetaAsset.Md5 != fileMd5)
                    {
                        state.UpdateResourceStatus(true, false, false, true, true);
                        UpdateStatus(tvi, "File needs saved to server.");
                        tvi.Background = _needUpdatedBrush;
                    }
                    else
                    {
                        state.UpdateResourceStatus(false, false, true, true, true);
                        UpdateStatus(tvi, "Loaded.");
                        tvi.Background = _normalBrush;
                    }
                }
                else
                {
                    throw new Exception("Unhandled event");
                }
            }

            SetResourceTreeSelectedIndex(-1);
        }