using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media.Imaging;
using JD.Serialization;
using JD.WPF.Extensions;
namespace JD.SceneExplorer.Utils
{
///
/// Manager allowing to get the editor icon associated to an actor tag.
///
public class EditorIconsManager
{
private static readonly EditorIconsManager m_instance;
private string m_dataBranch;
private BitmapImage m_allIconsMasterImage;
private List m_allIcons;
private bool m_initialized;
static EditorIconsManager()
{
m_instance = new EditorIconsManager();
}
public EditorIconsManager()
{
m_dataBranch = null;
m_allIconsMasterImage = null;
m_initialized = false;
m_allIcons = new List();
}
public static EditorIconsManager Instance { get { return m_instance; } }
public bool Initialized { get { return m_initialized; } }
public bool HasTags { get { return m_allIcons != null && m_allIcons.Count > 0; } }
public bool Init(string dataBranch)
{
if (String.IsNullOrEmpty(dataBranch))
return false;
m_dataBranch = dataBranch;
string pathToEditorIcons = m_dataBranch.TrimEnd('\\') + "\\EngineData\\editor\\icons\\tagIcons.tga";
if (!File.Exists(pathToEditorIcons))
return false;
m_allIconsMasterImage = TargaImageExtensions.LoadTargaImageAsBitmapImage(pathToEditorIcons);
if (m_allIconsMasterImage == null)
return false;
string pathToEditorIconsAtlas = m_dataBranch.TrimEnd('\\') + "\\EngineData\\editor\\icons\\tagIcons.atl";
AtlasList allAtlas = new AtlasList(pathToEditorIconsAtlas);
string pathToEditorIconsTagAssociation = m_dataBranch.TrimEnd('\\') + "\\EngineData\\editor\\icons\\tagIcons.tia";
TagIconAssociation allTagIconAssociations = new TagIconAssociation(pathToEditorIconsTagAssociation);
var allIconsEnum = from atlas in allAtlas.AllAtlas
from tagIconAssoc in allTagIconAssociations.AllTagIcons
where atlas.Index == tagIconAssoc.AtlasIndex
select new EditorIcon(atlas, tagIconAssoc, m_allIconsMasterImage);
m_allIcons = allIconsEnum.ToList();
m_initialized = true;
return true;
}
public BitmapSource GetIconLocationFromTag(string tag)
{
if (!HasTags)
return null;
tag = tag.ToLower();
EditorIcon icon = m_allIcons.FirstOrDefault(editorIcon => editorIcon.Tag == tag);
if (icon != null)
return icon.Image;
return null;
}
public bool IsLowPriorityTag(string tag)
{
if (!HasTags)
return false;
tag = tag.ToLower();
EditorIcon icon = m_allIcons.FirstOrDefault(editorIcon => editorIcon.Tag == tag);
if (icon != null)
return icon.LowPriority;
return false;
}
public BitmapSource GetIconLocationFromTags(IEnumerable tags)
{
BitmapSource imageLocation = null;
BitmapSource lowPrioImageLocation = null;
foreach (string tag in tags)
{
imageLocation = GetIconLocationFromTag(tag);
if (imageLocation != null)
{
if (IsLowPriorityTag(tag))
{
if(lowPrioImageLocation == null)
lowPrioImageLocation = imageLocation;
}
else
{
break;
}
}
}
if (imageLocation != null)
return imageLocation;
else
return lowPrioImageLocation;
}
private class EditorIcon
{
private readonly string m_tag;
private readonly BitmapSource m_image;
private readonly bool m_lowPriority;
public EditorIcon(Atlas iconAtlas, TagIcon tagIcon, BitmapImage imageSource)
{
if (iconAtlas.Index != tagIcon.AtlasIndex)
throw new InvalidOperationException("Atlas index is not matching. ");
m_tag = tagIcon.Tag.ToLower();
m_lowPriority = tagIcon.LowPriority;
Int32Rect imageSelection = new Int32Rect();
imageSelection.X = (int) (imageSource.PixelWidth * iconAtlas.Uv[0].Uv.X);
imageSelection.Y = (int) (imageSource.PixelHeight * iconAtlas.Uv[0].Uv.Y);
imageSelection.Width = (int) (imageSource.PixelWidth * (iconAtlas.Uv[1].Uv.X - iconAtlas.Uv[0].Uv.X) );
imageSelection.Height = (int) (imageSource.PixelHeight * (iconAtlas.Uv[1].Uv.Y - iconAtlas.Uv[0].Uv.Y) );
m_image = new CroppedBitmap(imageSource, imageSelection);
}
public string Tag { get { return m_tag; } }
///
/// Bitmap source used to display image.
///
public BitmapSource Image { get { return m_image; } }
public bool LowPriority { get { return m_lowPriority; } }
}
}
}