using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace PlantBox.Client.Forms.Controls.StatusBar
{
	[XamlCompilation(XamlCompilationOptions.Compile)]
	public partial class StatusBar : ContentView
	{
        // Progress
        public static readonly BindableProperty ProgressProperty = BindableProperty.Create(nameof(Progress), typeof(double), typeof(StatusBar), 0.5);
        public double Progress
        {
            get => (double)GetValue(ProgressProperty);
            set => SetValue(ProgressProperty, value);
        }
        // HintColor
        public static readonly BindableProperty HintColorProperty = BindableProperty.Create(nameof(HintColor), typeof(Color), typeof(StatusBar));
        public Color HintColor
        {
            get => (Color)GetValue(HintColorProperty);
            set => SetValue(HintColorProperty, value);
        }
        // ForegroundColor
        public static readonly BindableProperty ForegroundColorProperty = BindableProperty.Create(nameof(ForegroundColor), typeof(Color), typeof(StatusBar));
        public Color ForegroundColor
        {
            get => (Color)GetValue(ForegroundColorProperty);
            set => SetValue(ForegroundColorProperty, value);
        }
        // Image
        public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(Image), typeof(ImageSource), typeof(StatusBar));
        public ImageSource Image
        {
            get => (ImageSource)GetValue(ImageProperty);
            set => SetValue(ImageProperty, value);
        }
        // Label
        public static readonly BindableProperty LabelProperty = BindableProperty.Create(nameof(Label), typeof(string), typeof(StatusBar));
        public string Label
        {
            get => (string)GetValue(LabelProperty);
            set => SetValue(LabelProperty, value);
        }
        // BoundHeight
        public static readonly BindableProperty BoundHeightProperty = BindableProperty.Create(nameof(BoundHeight), typeof(double), typeof(StatusBar));
        public double BoundHeight
        {
            get => (double)GetValue(BoundHeightProperty);
            set => SetValue(BoundHeightProperty, value);
        }
        // BoundColor
        public static readonly BindableProperty BoundColorProperty = BindableProperty.Create(nameof(BoundColor), typeof(Color), typeof(StatusBar));
        public Color BoundColor
        {
            get => (Color)GetValue(BoundColorProperty);
            set => SetValue(BoundColorProperty, value);
        }
        // LowerBound
        public static readonly BindableProperty LowerBoundProperty = BindableProperty.Create(nameof(LowerBound), typeof(double), typeof(StatusBar), 0.2);
        public double LowerBound
        {
            get => (double)GetValue(LowerBoundProperty);
            set => SetValue(LowerBoundProperty, value);
        }
        // UpperBound
        public static readonly BindableProperty UpperBoundProperty = BindableProperty.Create(nameof(UpperBound), typeof(double), typeof(StatusBar), 0.8);
        public double UpperBound
        {
            get => (double)GetValue(UpperBoundProperty);
            set => SetValue(UpperBoundProperty, value);
        }

        public StatusBar()
		{
			InitializeComponent();

            AbsoluteLayout.SetLayoutFlags(UpperBoundBar, AbsoluteLayoutFlags.PositionProportional | AbsoluteLayoutFlags.WidthProportional);
            AbsoluteLayout.SetLayoutFlags(LowerBoundBar, AbsoluteLayoutFlags.PositionProportional | AbsoluteLayoutFlags.WidthProportional);
		}

        protected override void OnPropertyChanged([CallerMemberName]string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            if (propertyName == ProgressProperty.PropertyName)
            {
                new Animation
                (
                    x => AbsoluteLayout.SetLayoutBounds(ForegroundBar, new Rectangle(0, 1, 1, x)),
                    AbsoluteLayout.GetLayoutBounds(ForegroundBar).Height,
                    Progress,
                    Easing.CubicInOut
                ).Commit(this, "Scale", 16, 1000);
            }
            if (propertyName == HintColorProperty.PropertyName)
            {
                BackgroundBar.BackgroundColor = HintColor;
            }
            if (propertyName == ForegroundColorProperty.PropertyName)
            {
                ForegroundBar.BackgroundColor = ForegroundColor;
                label.TextColor = ForegroundColor;
            }
            if (propertyName == ImageProperty.PropertyName)
            {
                image.Source = Image;
            }
            if (propertyName == LabelProperty.PropertyName)
            {
                label.Text = Label;
            }
            if (propertyName == BoundHeightProperty.PropertyName || propertyName == LowerBoundProperty.PropertyName || propertyName == UpperBoundProperty.PropertyName)
            {
                // Y axis is reversed
                double realBoundHeight = BoundHeight / BackgroundBar.Height;
                AbsoluteLayout.SetLayoutBounds(LowerBoundBar, new Rectangle(0, 1 - LowerBound, 1, BoundHeight));
                AbsoluteLayout.SetLayoutBounds(UpperBoundBar, new Rectangle(0, 1 - UpperBound, 1, BoundHeight));
            }
            if (propertyName == BoundColorProperty.PropertyName)
            {
                LowerBoundBar.BackgroundColor = BoundColor;
                UpperBoundBar.BackgroundColor = BoundColor;
            }
        }
    }
}