using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using Telerik.Web.UI;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;


/// <summary>
/// Specifies the advanced form mode.
/// </summary>
public enum AdvancedFormMode
{
    Insert,
    Edit
}

public partial class RadSchedulerAdvancedFormAdvancedForm : System.Web.UI.UserControl
{
    #region Private members

    private string _selectedCountry; 

    private bool FormInitialized
    {
        get
        {
            return (bool)(ViewState["FormInitialized"] ?? false);
        }

        set
        {
            ViewState["FormInitialized"] = value;
        }
    }

    private AdvancedFormMode mode = AdvancedFormMode.Insert;

    #endregion

    #region Protected properties

    protected RadScheduler Owner
    {
        get
        {
            return Appointment.Owner;
        }
    }

    protected Appointment Appointment
    {
        get
        {
            SchedulerFormContainer container = (SchedulerFormContainer)BindingContainer;
            return container.Appointment;
        }
    }

    #endregion

    #region Attributes and resources

    //Continent, Coutry   
    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public string Continent
    {
        get
        {
            return ContinentsRadComboBox.SelectedValue;
        }

        set
        {
            ContinentsRadComboBox.SelectedValue = value;
        }
    }

    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public string Country
    {
        get
        {
            return CountriesRadComboBox.SelectedValue;
        }

        set
        {
            // Store the selected country ID until we obtain the continent ID   
            _selectedCountry = value;
        }
    }


    protected void LoadContinents()
    {
        SqlConnection connection = new SqlConnection(
        ConfigurationManager.ConnectionStrings["TelerikConnectionString"].ConnectionString);

        SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Continents ORDER By Name", connection);
        DataTable dt = new DataTable();
        adapter.Fill(dt);
        ContinentsRadComboBox.Items.Clear();
        ContinentsRadComboBox.Items.Insert(0, new RadComboBoxItem("- Select a continent -"));
        ContinentsRadComboBox.AppendDataBoundItems = true;
        ContinentsRadComboBox.DataTextField = "Name";
        ContinentsRadComboBox.DataValueField = "ID";
        ContinentsRadComboBox.DataSource = dt;
        ContinentsRadComboBox.DataBind();
        ContinentsRadComboBox.DataSource = null;
        //insert the first item   

    }

    protected void LoadCountries(string continentID)
    {
        SqlConnection connection = new SqlConnection(
        ConfigurationManager.ConnectionStrings["TelerikConnectionString"].ConnectionString);

        //select a country based on the continentID   
        SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Countries WHERE ContinentID=@ContinentID ORDER By Name", connection);
        adapter.SelectCommand.Parameters.AddWithValue("@ContinentID", continentID);

        DataTable dt = new DataTable();
        adapter.Fill(dt);

        CountriesRadComboBox.DataTextField = "Name";
        CountriesRadComboBox.DataValueField = "ID";
        CountriesRadComboBox.DataSource = dt;
        CountriesRadComboBox.DataBind();
    }

    protected void CountriesRadComboBox_ItemsRequested(object o, RadComboBoxItemsRequestedEventArgs e)
    {
        // e.Text is the first parameter of the requestItems method    
        // invoked in LoadCountries method    
        LoadCountries(e.Text);
    }  


    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public string Description
    {
        get
        {
            return DescriptionText.Text;
        }

        set
        {
            DescriptionText.Text = value;
        }
    }

  


    #endregion

    #region Public properties

    public AdvancedFormMode Mode
    {
        get
        {
            return mode;
        }
        set
        {
            mode = value;
        }
    }

    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public string Subject
    {
        get
        {
            return SubjectText.Text;
        }

        set
        {
            SubjectText.Text = value;
        }
    }

    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public DateTime Start
    {
        get
        {
            DateTime result = StartDate.SelectedDate.Value.Date;

            if (AllDayEvent.Checked)
            {
                result = result.Date;
            }
            else
            {
                TimeSpan time = StartTime.SelectedDate.Value.TimeOfDay;
                result = result.Add(time);
            }

            return Owner.DisplayToUtc(result);
        }

        set
        {
            StartDate.SelectedDate = Owner.UtcToDisplay(value);
            StartTime.SelectedDate = Owner.UtcToDisplay(value);
        }
    }

    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public DateTime End
    {
        get
        {
            DateTime result = EndDate.SelectedDate.Value.Date;

            if (AllDayEvent.Checked)
            {
                result = result.Date.AddDays(1);
            }
            else
            {
                TimeSpan time = EndTime.SelectedDate.Value.TimeOfDay;
                result = result.Add(time);
            }

            return Owner.DisplayToUtc(result);
        }

        set
        {
            EndDate.SelectedDate = Owner.UtcToDisplay(value);
            EndTime.SelectedDate = Owner.UtcToDisplay(value);
        }
    }


    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public string RecurrenceRuleText
    {
        get
        {
            if (Owner.RecurrenceSupport)
            {
                bool dateSpecified = StartDate.SelectedDate.HasValue && EndDate.SelectedDate.HasValue;
                bool timeSpecified = StartTime.SelectedDate.HasValue && EndTime.SelectedDate.HasValue;

                if ((AllDayEvent.Checked && !dateSpecified) ||
                    (!AllDayEvent.Checked && !(dateSpecified && timeSpecified)))
                {
                    return string.Empty;
                }

                AppointmentRecurrenceEditor.StartDate = Start;
                AppointmentRecurrenceEditor.EndDate = End;

                RecurrenceRule rrule = AppointmentRecurrenceEditor.RecurrenceRule;

                if (rrule == null)
                {
                    return string.Empty;
                }

                RecurrenceRule originalRule;
                if (RecurrenceRule.TryParse(OriginalRecurrenceRule.Value, out originalRule))
                {
                    rrule.Exceptions = originalRule.Exceptions;
                }

                if (rrule.Range.RecursUntil != DateTime.MaxValue)
                {
                    rrule.Range.RecursUntil = Owner.DisplayToUtc(rrule.Range.RecursUntil);

                    if (!AllDayEvent.Checked)
                    {
                        rrule.Range.RecursUntil = rrule.Range.RecursUntil.AddDays(1);
                    }
                }

                return rrule.ToString();
            }

            return string.Empty;
        }

        set
        {
            RecurrenceRule rrule;
            RecurrenceRule.TryParse(value, out rrule);

            if (rrule != null)
            {
                if (rrule.Range.RecursUntil != DateTime.MaxValue)
                {
                    DateTime recursUntil = Owner.UtcToDisplay(rrule.Range.RecursUntil);

                    if (!IsAllDayAppointment(Appointment))
                    {
                        recursUntil = recursUntil.AddDays(-1);
                    }

                    rrule.Range.RecursUntil = recursUntil;
                }

                AppointmentRecurrenceEditor.RecurrenceRule = rrule;

                OriginalRecurrenceRule.Value = value;
            }
        }
    }

    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public string Reminder
    {
        get
        {
            if (Owner.RemindersSupport && ReminderDropDown.SelectedValue != string.Empty)
            {
                return ReminderDropDown.SelectedValue;
            }

            return string.Empty;
        }

        set
        {
            RadComboBoxItem item = ReminderDropDown.Items.FindItemByValue(value);
            if (item != null)
            {
                item.Selected = true;
            }
        }
    }

    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
    public string TimeZoneID
    {
        get
        {
            return TimeZonesDropDown.SelectedValue;
        }

        set
        {

            RadComboBoxItem item = TimeZonesDropDown.Items.FindItemByValue(value);
            if (item != null)
            {
                item.Selected = true;
            }
        }
    }

    #endregion

    protected void Page_Load(object sender, EventArgs e)
    {
        if (ContinentsRadComboBox.Items.Count == 0)
        {
            // Fill the continents combo   
            LoadContinents();
        }  

        UpdateButton.ValidationGroup = Owner.ValidationGroup;
        UpdateButton.CommandName = Mode == AdvancedFormMode.Edit ? "Update" : "Insert";

        if (Owner.AdvancedForm.EnableTimeZonesEditing)
            PopulateTimeZonesDropDown();
        else
            TimeZonesDropDown.Visible = false;

        if (!Owner.Reminders.Enabled)
            ReminderDropDown.Visible = false;

        InitializeStrings();
        InitializeRecurrenceEditor();

        if (!FormInitialized)
        {
            UpdateResetExceptionsVisibility();
        }
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (!string.IsNullOrEmpty(_selectedCountry))
        {
            // Fill the countries combo.   
            // Note that Continent value is available in PreRender   
            LoadCountries(Continent);
            CountriesRadComboBox.SelectedValue = _selectedCountry;
        }  


        if (!FormInitialized)
        {
            if (IsAllDayAppointment(Appointment))
            {
                EndDate.SelectedDate = EndDate.SelectedDate.Value.AddDays(-1);
            }

            FormInitialized = true;
        }

        if (String.IsNullOrEmpty(Appointment.TimeZoneID))
            TimeZoneID = Owner.TimeZonesProvider.OperationTimeZone.TimeZoneId;
        else
            TimeZoneID = Appointment.TimeZoneID;
    }

    private void PopulateTimeZonesDropDown()
    {
        TimeZonesDropDown.DataSource = Owner.TimeZonesProvider.GetAllTimeZones();
        TimeZonesDropDown.DataTextField = "DisplayName";
        TimeZonesDropDown.DataValueField = "Id";
    }

    protected void BasicControlsPanel_DataBinding(object sender, EventArgs e)
    {
        AllDayEvent.Checked = IsAllDayAppointment(Appointment);
    }

    protected void DurationValidator_OnServerValidate(object source, ServerValidateEventArgs args)
    {
        args.IsValid = (End - Start) > TimeSpan.Zero;
    }

    protected void ResetExceptions_OnClick(object sender, EventArgs e)
    {
        Owner.RemoveRecurrenceExceptions(Appointment);
        OriginalRecurrenceRule.Value = Appointment.RecurrenceRule;
        ResetExceptions.Text = Owner.Localization.AdvancedDone;
    }

    #region Private methods

    private void InitializeStrings()
    {
        SubjectValidator.ErrorMessage = Owner.Localization.AdvancedSubjectRequired;
        SubjectValidator.ValidationGroup = Owner.ValidationGroup;

        AllDayEvent.Text = Owner.Localization.AdvancedAllDayEvent;

        StartDateValidator.ErrorMessage = Owner.Localization.AdvancedStartDateRequired;
        StartDateValidator.ValidationGroup = Owner.ValidationGroup;

        StartTimeValidator.ErrorMessage = Owner.Localization.AdvancedStartTimeRequired;
        StartTimeValidator.ValidationGroup = Owner.ValidationGroup;

        EndDateValidator.ErrorMessage = Owner.Localization.AdvancedEndDateRequired;
        EndDateValidator.ValidationGroup = Owner.ValidationGroup;

        EndTimeValidator.ErrorMessage = Owner.Localization.AdvancedEndTimeRequired;
        EndTimeValidator.ValidationGroup = Owner.ValidationGroup;

        DurationValidator.ErrorMessage = Owner.Localization.AdvancedStartTimeBeforeEndTime;
        DurationValidator.ValidationGroup = Owner.ValidationGroup;

        ResetExceptions.Text = Owner.Localization.AdvancedReset;

        SharedCalendar.FastNavigationSettings.OkButtonCaption = Owner.Localization.AdvancedCalendarOK;
        SharedCalendar.FastNavigationSettings.CancelButtonCaption = Owner.Localization.AdvancedCalendarCancel;
        SharedCalendar.FastNavigationSettings.TodayButtonCaption = Owner.Localization.AdvancedCalendarToday;
    }

    private void InitializeRecurrenceEditor()
    {
        AppointmentRecurrenceEditor.SharedCalendar = SharedCalendar;
        AppointmentRecurrenceEditor.Culture = Owner.Culture;
        AppointmentRecurrenceEditor.StartDate = Appointment.Start;
        AppointmentRecurrenceEditor.EndDate = Appointment.End;
    }

    private void UpdateResetExceptionsVisibility()
    {
        // Render the reset exceptions checkbox when using web service binding
        if (string.IsNullOrEmpty(Owner.WebServiceSettings.Path))
        {
            ResetExceptions.Visible = false;
            RecurrenceRule rrule;
            if (RecurrenceRule.TryParse(Appointment.RecurrenceRule, out rrule))
            {
                ResetExceptions.Visible = rrule.Exceptions.Count > 0;
            }
        }
    }

    private bool IsAllDayAppointment(Appointment appointment)
    {
        DateTime displayStart = Owner.UtcToDisplay(appointment.Start);
        DateTime displayEnd = Owner.UtcToDisplay(appointment.End);
        return displayStart.CompareTo(displayStart.Date) == 0 && displayEnd.CompareTo(displayEnd.Date) == 0;
    }

    #endregion
}
