namespace CSharp.SilverlightDemo
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.ServiceModel;
    using System.Windows;
    using System.Windows.Browser;
    using System.Windows.Controls;
    using Telerik.Reporting.Service.SilverlightClient;
    using Telerik.Reporting.Service;
    using Telerik.ReportViewer.Silverlight;

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }

    public class MainPageModel : INotifyPropertyChanged
    {
        static readonly ReportInfo noReportInfo = new ReportInfo { Name = "No report." };
        static readonly ReportInfo loadingReportInfo = new ReportInfo { Name = "Loading reports..." };

        ReportServiceClient serviceClient;
        string reportServiceUri;
        bool hasReports;
        ReportInfo selectedReportInfo;
        IList<ReportInfo> availableReports;

        public event PropertyChangedEventHandler PropertyChanged;

        public ReportInfo SelectedReport
        {
            get { return this.selectedReportInfo; }
            set
            {
                this.selectedReportInfo = value;
                this.NotifyPropertyChanged("SelectedReport");
            }
        }

        public string ReportServiceUri
        {
            get { return this.reportServiceUri; }
            set
            {
                if (null != this.serviceClient)
                {
                    this.serviceClient.ListAvailableReportsCompleted -= this.OnListAvailableReportsCompleted;
                    this.serviceClient = null;
                }

                this.reportServiceUri = value;
                this.NotifyPropertyChanged("ReportServiceUri");

                if (!string.IsNullOrEmpty(this.reportServiceUri) && !DesignerProperties.IsInDesignTool)
                {
                    this.serviceClient = new ReportServiceClient(ReportViewer.EnsureAbsoluteUri(new Uri(this.reportServiceUri, UriKind.RelativeOrAbsolute)));
                    this.serviceClient.ListAvailableReportsCompleted += this.OnListAvailableReportsCompleted;
                    this.BeginLoadReports();
                }
            }
        }

        public bool HasReports
        {
            get { return this.hasReports; }
            set
            {
                this.hasReports = value;
                this.NotifyPropertyChanged("HasReports");
            }
        }

        public IList<ReportInfo> AvailableReports
        {
            get { return this.availableReports; }
            set
            {
                this.availableReports = value;
                this.NotifyPropertyChanged("AvailableReports");
            }
        }

        public MainPageModel()
        {
            this.HasReports = false;
        }

        void BeginLoadReports()
        {
            this.HasReports = false;
            
            this.AvailableReports = new [] { loadingReportInfo };
            this.SelectedReport = this.AvailableReports[0];

            this.serviceClient.ListAvailableReportsAsync();
        }

        void OnListAvailableReportsCompleted(object sender, ListAvailableReportsEventArgs e)
        {
            var reportAvailable = false;
            var reports = e.Reports;
            if (null != reports && reports.Count > 0)
            {
                this.AvailableReports = reports;
                reportAvailable = true;
            }
            else
            {
                this.AvailableReports = new[] { noReportInfo };
            }

            this.HasReports = reportAvailable;
            this.SelectedReport = this.AvailableReports[0];
        }

        void NotifyPropertyChanged(string propertyName)
        {
            if (null != this.PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
