using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml;
using System.IO;
using System.Xml.Linq;
using System.Windows.Markup;
using System.Reflection;

namespace GaugeBuilder
{
    public class Wrapper<T>
    {
        public string Xaml { get; set; }
        public string Name { get; set; }

        public T Element 
        {
            get 
            {
                return (T)XamlReader.Load(Xaml);
            }
        }
    }

    public static class ResourcesHelper
    {
        public static Wrapper<T> Build<T>(T tObject, string xaml)
            where T: DependencyObject
        {
            return new Wrapper<T>()
            {
                Xaml = xaml,
                Name = (tObject == default(T)) 
                        ? "-- Default --"
                        : (string)tObject.GetValue(FrameworkElement.NameProperty)
            };
        }

        public static List<Wrapper<T>> GetResources<T>(bool addDefault, params string[] resourceUris) 
            where T : DependencyObject
        {
            List<Wrapper<T>> elements = new List<Wrapper<T>>();

            // add default item
            if (addDefault) 
            {
                elements.Add(Build<T>(default(T), string.Empty));
            }

            // iterate by the resources
            foreach (var resUri in resourceUris)
	        {
                var uri = "GaugeBuilder.Resources." + resUri;
                var doc = GetDocument(typeof(ResourcesHelper).Assembly, uri);
                if (doc != null)
                {
                    // generate items
                    foreach (var elem in GetResources<T>(doc.Root.Elements()))
                    {
                        elements.Add(Build<T>(elem.Key, elem.Value));
                    }
                }
	        }

            return elements;
        }


        public static List<KeyValuePair<T, string>> GetResources<T>(IEnumerable<XElement> resourceElements)
            where T: class
        {
            var list = new List<KeyValuePair<T, string>>();

            foreach (var elem in resourceElements)
            {
                var tObject = XamlReader.Load(elem.ToString()) as T;
                if (tObject != null)
                {
                    list.Add(new KeyValuePair<T, string>(tObject, elem.ToString()));
                }
            }

            return list;
        }

        private static XDocument GetDocument(Assembly assembly, string resourceName)
        {
            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
            {
                if (stream != null)
                {
                    return XDocument.Load(stream);
                }
            }
            return null;
        }
    }
}
