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 BeWo.Core
{
    [MarkupExtensionReturnType(typeof(object))]
    public abstract class BindingDecoratorBase : MarkupExtension
    {
        private Binding _WrappedBinding = new Binding();

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

            set
            {
                this._WrappedBinding.AsyncState = value;
            }
        }

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

            set
            {
                this._WrappedBinding = value;
            }
        }

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

            set
            {
                this._WrappedBinding.BindsDirectlyToSource = value;
            }
        }

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

            set
            {
                this._WrappedBinding.Converter = value;
            }
        }

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

            set
            {
                this._WrappedBinding.ConverterCulture = value;
            }
        }

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

            set
            {
                this._WrappedBinding.ConverterParameter = value;
            }
        }

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

            set
            {
                this._WrappedBinding.ElementName = value;
            }
        }

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

            set
            {
                this._WrappedBinding.FallbackValue = value;
            }
        }

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

            set
            {
                this._WrappedBinding.IsAsync = value;
            }
        }

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

            set
            {
                this._WrappedBinding.Mode = value;
            }
        }

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

            set
            {
                this._WrappedBinding.NotifyOnSourceUpdated = value;
            }
        }

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

            set
            {
                this._WrappedBinding.NotifyOnTargetUpdated = value;
            }
        }

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

            set
            {
                this._WrappedBinding.NotifyOnValidationError = value;
            }
        }

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

            set
            {
                this._WrappedBinding.Path = value;
            }
        }

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

            set
            {
                this._WrappedBinding.RelativeSource = value;
            }
        }

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

            set
            {
                this._WrappedBinding.Source = value;
            }
        }

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

            set
            {
                this._WrappedBinding.UpdateSourceExceptionFilter = value;
            }
        }

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

            set
            {
                this._WrappedBinding.UpdateSourceTrigger = value;
            }
        }

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

            set
            {
                this._WrappedBinding.ValidatesOnDataErrors = value;
            }
        }

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

            set
            {
                this._WrappedBinding.ValidatesOnExceptions = value;
            }
        }

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

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

            set
            {
                this._WrappedBinding.XPath = value;
            }
        }

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

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

            IProvideValueTarget 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;
        }
    }
}