private void tvAssets_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                TreeNode tn = tvAssets.GetNodeAt(e.X, e.Y);
                tvAssets.SelectedNode = tn;
                AssetTreeNode atn = tn as AssetTreeNode;
                for (int i = 0; i < cmsAssets.Items.Count; i++)
                {
                    cmsAssets.Items[i].Visible = true;
                }
                // this is a folder
                if (atn == null)
                {
                    cmsAssets.Items[3].Visible = cmsAssets.Items[4].Visible = cmsAssets.Items[5].Visible = cmsAssets.Items[6].Visible = false;
                }
                // this is an asset
                else
                {
                    // show the add menu only if the user right-clicked a folder
                    cmsAssets.Items[2].Visible = cmsAssets.Items[3].Visible = false;
                    cmsAssets.Items[4].Enabled = cmsAssets.Items[6].Enabled = !atn.Asset.bReadOnly;
                }

                cmsAssets.Show(tvAssets, e.X, e.Y);
            }
        }
        private void framesToolStripMenuItem3_Click(object sender, EventArgs e)
        {
            Frames f = new Frames();

            f.Filename = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + Frames.FileExtension;
            f.FilePath = GetFullPathForNode(tvAssets.SelectedNode);
            AssetTreeNode atn = new AssetTreeNode(f.Filename, (int)EAssetImageList.Frames, (int)EAssetImageList.Frames, f);

            tvAssets.SelectedNode.Nodes.Add(atn);
            CachedAsset ca = GetCachedAssetForNode(tvAssets.SelectedNode);

            ca.AddAsset(GetRelativePathForNode(atn));
        }
        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tvAssets.SelectedNode.Parent == null)
            {
                string title = tvAssets.SelectedNode.Text;
                string path  = Globals.AppSettings.GetPathForTitle(tvAssets.SelectedNode.Text);

                // change this to a proper unload+clear
                TreeNode sn = tvAssets.SelectedNode;
                tvAssets.SelectedNode = null;
                tvAssets.Nodes.Remove(sn);
                CachedAsset ca = Globals.AppSettings.CachedAssets.Find(tca => title == tca.Title);
                if (ca != null)
                {
                    ca.Assets = AddAssetPath(title, path, null);
                }
            }
            else if (tvAssets.SelectedNode.Text.EndsWith(LuaScriptAsset.FileExtension))
            {
            }
            else if (tvAssets.SelectedNode.Text.EndsWith(Animation.FileExtension))
            {
            }
            else if (tvAssets.SelectedNode.Text.EndsWith(Frames.FileExtension))
            {
                // delete the existing asset and load from file
                AssetTreeNode atn = tvAssets.SelectedNode as AssetTreeNode;
                UnsetWorkingFrames();
                atn.Asset = null;
                tvAssets_AfterSelect(tvAssets, new TreeViewEventArgs(atn));
            }
            else
            {
                string      title = tvAssets.SelectedNode.Text;
                string      path  = GetRelativePathForNode(tvAssets.SelectedNode);
                CachedAsset ca    = GetCachedAssetForNode(tvAssets.SelectedNode);

                // change this to a proper unload+clear
                TreeNode sn = tvAssets.SelectedNode;
                TreeNode pn = sn.Parent;
                tvAssets.SelectedNode = null;
                tvAssets.Nodes.Remove(sn);
                int i = ca.Assets.FindIndex(a => a.StartsWith(path));
                ca.Assets.RemoveAll(tca => tca.StartsWith(path + '\\'));
                List <string> foundlist = AddAssetPath(title, ca.Path + path, pn);
                ca.Assets.InsertRange(i, foundlist);
            }
        }
        void UpdateFilePaths(TreeNode tn, string path)
        {
            AssetTreeNode atn = tn as AssetTreeNode;

            if (atn != null)
            {
                atn.Asset.FilePath = path;
            }
            else
            {
                string np = Path.Combine(path, tn.Text);
                foreach (TreeNode t in tn.Nodes)
                {
                    UpdateFilePaths(t, np);
                }
            }
        }
        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AssetTreeNode atn = tvAssets.SelectedNode as AssetTreeNode;

            if (atn == null)
            {
                return;
            }
            if (DialogResult.Yes == MessageBox.Show("Are you sure you want to delete " + atn.Text + "? This operation permanently deletes the file.", "Deletion Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
            {
                try
                {
                    File.Delete(Path.Combine(atn.Asset.Filename, atn.Asset.FilePath));
                    UnsetWorkingFrames();
                    atn.Remove();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message, "Deletion error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
        }
        private void tvAssets_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (string.IsNullOrEmpty(e.Label))
            {
                e.CancelEdit = true;
                return;
            }

            AssetTreeNode atn = e.Node as AssetTreeNode;

            // renaming an asset file
            if (atn != null)
            {
                if (((atn.Asset is Frames) && !e.Label.EndsWith(Frames.FileExtension)) ||
                    ((atn.Asset is Animation) && !e.Label.EndsWith(Animation.FileExtension)) ||
                    ((atn.Asset is LuaScriptAsset) && !e.Label.EndsWith(LuaScriptAsset.FileExtension)))
                {
                    MessageBox.Show("The file extension must the file type!", "File extension error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    e.CancelEdit = true;
                    return;
                }

                if (File.Exists(Path.Combine(atn.Asset.FilePath, e.Label)))
                {
                    MessageBox.Show("The new file name must not already be in use!", "Existing file error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    e.CancelEdit = true;
                    return;
                }

                try
                {
                    if (File.Exists(Path.Combine(atn.Asset.FilePath, atn.Asset.Filename)))
                    {
                        File.Move(Path.Combine(atn.Asset.FilePath, atn.Asset.Filename), Path.Combine(atn.Asset.FilePath, e.Label));
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message, "File rename error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    e.CancelEdit = true;
                    return;
                }

                CachedAsset ca = GetCachedAssetForNode(e.Node);
                ca.RenameAsset(atn.Asset.Filename, e.Label);
                atn.Asset.Filename = e.Label;
            }
            else
            {
                string dirpath = GetFullPathForNode(e.Node.Parent);

                if (Directory.Exists(Path.Combine(dirpath, e.Label)))
                {
                    MessageBox.Show("The new directory name already exists!", "Existing directory error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    e.CancelEdit = true;
                    return;
                }

                try
                {
                    Directory.Move(Path.Combine(dirpath, e.Node.Text), Path.Combine(dirpath, e.Label));
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message, "Directory rename error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    e.CancelEdit = true;
                    return;
                }

                // all assets under this branch need their paths recalculated
                UpdateFilePaths(e.Node, Path.Combine(dirpath, e.Label));
            }
        }
        private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            AssetTreeNode atn = tvAssets.SelectedNode as AssetTreeNode;

            atn.Asset.SaveToFile();
        }