using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;

namespace ValidationLibrary
{
    [MarkupExtensionReturnType(typeof (object))]
    public abstract class BindingDecoratorBase : MarkupExtension
    {
        private Binding _WrappedBinding = new Binding();

        [DefaultValue(null)]
        public object AsyncState
        {
            get { return _WrappedBinding.AsyncState; }

            set { _WrappedBinding.AsyncState = value; }
        }

        [Browsable(false)]
        public Binding Binding
        {
            get { return _WrappedBinding; }

            set { _WrappedBinding = value; }
        }

        [DefaultValue(false)]
        public bool BindsDirectlyToSource
        {
            get { return _WrappedBinding.BindsDirectlyToSource; }

            set { _WrappedBinding.BindsDirectlyToSource = value; }
        }

        [DefaultValue(null)]
        public IValueConverter Converter
        {
            get { return _WrappedBinding.Converter; }

            set { _WrappedBinding.Converter = value; }
        }

        [TypeConverter(typeof (CultureInfoIetfLanguageTagConverter))]
        [DefaultValue(null)]
        public CultureInfo ConverterCulture
        {
            get { return _WrappedBinding.ConverterCulture; }

            set { _WrappedBinding.ConverterCulture = value; }
        }

        [DefaultValue(null)]
        public object ConverterParameter
        {
            get { return _WrappedBinding.ConverterParameter; }

            set { _WrappedBinding.ConverterParameter = value; }
        }

        [DefaultValue(null)]
        public string ElementName
        {
            get { return _WrappedBinding.ElementName; }

            set { _WrappedBinding.ElementName = value; }
        }

        [DefaultValue(null)]
        public object FallbackValue
        {
            get { return _WrappedBinding.FallbackValue; }

            set { _WrappedBinding.FallbackValue = value; }
        }

        [DefaultValue(false)]
        public bool IsAsync
        {
            get { return _WrappedBinding.IsAsync; }

            set { _WrappedBinding.IsAsync = value; }
        }

        [DefaultValue(BindingMode.Default)]
        public BindingMode Mode
        {
            get { return _WrappedBinding.Mode; }

            set { _WrappedBinding.Mode = value; }
        }

        [DefaultValue(false)]
        public bool NotifyOnSourceUpdated
        {
            get { return _WrappedBinding.NotifyOnSourceUpdated; }

            set { _WrappedBinding.NotifyOnSourceUpdated = value; }
        }

        [DefaultValue(false)]
        public bool NotifyOnTargetUpdated
        {
            get { return _WrappedBinding.NotifyOnTargetUpdated; }

            set { _WrappedBinding.NotifyOnTargetUpdated = value; }
        }

        [DefaultValue(false)]
        public bool NotifyOnValidationError
        {
            get { return _WrappedBinding.NotifyOnValidationError; }

            set { _WrappedBinding.NotifyOnValidationError = value; }
        }

        [DefaultValue(null)]
        public PropertyPath Path
        {
            get { return _WrappedBinding.Path; }

            set { _WrappedBinding.Path = value; }
        }

        [DefaultValue(null)]
        public RelativeSource RelativeSource
        {
            get { return _WrappedBinding.RelativeSource; }

            set { _WrappedBinding.RelativeSource = value; }
        }

        [DefaultValue(null)]
        public object Source
        {
            get { return _WrappedBinding.Source; }

            set { _WrappedBinding.Source = value; }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public UpdateSourceExceptionFilterCallback UpdateSourceExceptionFilter
        {
            get { return _WrappedBinding.UpdateSourceExceptionFilter; }

            set { _WrappedBinding.UpdateSourceExceptionFilter = value; }
        }

        [DefaultValue(UpdateSourceTrigger.Default)]
        public UpdateSourceTrigger UpdateSourceTrigger
        {
            get { return _WrappedBinding.UpdateSourceTrigger; }

            set { _WrappedBinding.UpdateSourceTrigger = value; }
        }

        [DefaultValue(false)]
        public bool ValidatesOnDataErrors
        {
            get { return _WrappedBinding.ValidatesOnDataErrors; }

            set { _WrappedBinding.ValidatesOnDataErrors = value; }
        }

        [DefaultValue(false)]
        public bool ValidatesOnExceptions
        {
            get { return _WrappedBinding.ValidatesOnExceptions; }

            set { _WrappedBinding.ValidatesOnExceptions = value; }
        }

        [DefaultValue(null)]
        public Collection<ValidationRule> ValidationRules
        {
            get { return _WrappedBinding.ValidationRules; }
        }

        [DefaultValue(null)]
        public string XPath
        {
            get { return _WrappedBinding.XPath; }

            set { _WrappedBinding.XPath = value; }
        }

        public override object ProvideValue(IServiceProvider pProvider)
        {
            return _WrappedBinding.ProvideValue(pProvider);
        }

        protected virtual bool TryGetTargetItems(IServiceProvider pProvider, out DependencyObject pTarget, out DependencyProperty pDP)
        {
            pTarget = null;
            pDP = null;
            if (pProvider == null)
            {
                return false;
            }

            var service = (IProvideValueTarget) pProvider.GetService(typeof (IProvideValueTarget));
            if (service == null)
            {
                return false;
            }

            pTarget = service.TargetObject as DependencyObject;
            pDP = service.TargetProperty as DependencyProperty;
            return pTarget != null && pDP != null;
        }
    }
}