package Uploader::GUI::DlgCommon;
use strict;
use Wx::Calendar;
use Wx::Locale qw/:default/;

use base qw/
               Class::Accessor::Fast
           /; 

__PACKAGE__->mk_accessors(     
    qw/
        properties
        frame_callback
      /
);

sub InitHandler {
    my ( $self ) = @_;

    # to connect the right event handler to each control
    my $ctrl_handlers = {
        'Wx::SpinCtrl' => sub { my ( $ctrl ) = @_; Wx::Event::EVT_SPINCTRL( $ctrl, $ctrl, sub { $self->OnSpinCtrl(@_) } ); },
        'Wx::TextCtrl' => sub { my ( $ctrl ) = @_; Wx::Event::EVT_TEXT( $ctrl, $ctrl, sub { $self->OnTextCtrl(@_) } ); },
        'Wx::Choice' => sub { my ( $ctrl ) = @_; Wx::Event::EVT_CHOICE( $ctrl, $ctrl, sub { $self->OnChoice(@_) } ); },
        'Wx::CheckBox' => sub { my ( $ctrl ) = @_; Wx::Event::EVT_CHECKBOX( $ctrl, $ctrl, sub { $self->OnCheckBox(@_) } ); },
        'Wx::DatePickerCtrl' => sub { my ( $ctrl ) = @_; Wx::Event::EVT_DATE_CHANGED( $ctrl, $ctrl, sub { $self->OnDatePicker(@_) } ); },
    };
    
    map {
        my $ctrl =$self->FindWindow($_);
        if(defined $ctrl){
            $ctrl_handlers->{ ref $ctrl}->($ctrl) if exists $ctrl_handlers->{ ref $ctrl};

            $ctrl->SetValidator(
                $self->properties->{$_}->{validator}
            ) if exists $self->properties->{$_}->{validator};
        }
    }
    keys %{$self->properties};
    

}

# what does happen when the text changes
sub OnCheckBox {
    my ( $self, $ctrl, $event ) = @_;
    
    my $id = $ctrl->GetId;
    # change the property value
    $self->properties->{$id}->{value}->(
        $event->IsChecked
    ) if exists $self->properties->{$id}->{value};

    # exec the callback
    $self->properties->{$id}->{frame_callback}->($self, $ctrl, $event) if exists
        $self->properties->{$id}->{frame_callback};    

    $event->Skip;
}


# what does happen when the text changes
sub OnTextCtrl {
    my ( $self, $ctrl, $event ) = @_;
    
    my $id = $ctrl->GetId;
    # change the property value
    $self->properties->{$id}->{value}->(
        $event->GetString
    ) if exists $self->properties->{$id}->{value};

    # exec the callback
    $self->properties->{$id}->{frame_callback}->($self, $ctrl, $event) if exists
        $self->properties->{$id}->{frame_callback};    
    
    $event->Skip;
}

sub OnSpinCtrl {
    my ( $self, $ctrl, $event ) = @_;
    
    my $id = $ctrl->GetId;
    # change the property value
    $self->properties->{$id}->{value}->(
        $event->GetInt
    ) if exists $self->properties->{$id}->{value};

    # exec the callback
    $self->properties->{$id}->{frame_callback}->($self, $ctrl, $event) if exists
        $self->properties->{$id}->{frame_callback};    
    
    $event->Skip;
}


sub OnChoice {
    my ( $self, $ctrl, $event ) = @_;
    
    my $id = $ctrl->GetId;

    # if a preprocess value is required
    my $value = exists $self->properties->{$id}->{string_selection} ? $event->GetString : $event->GetSelection;
    $value = $self->properties->{$id}->{pre_process}->( $value ) if exists
        $self->properties->{$id}->{pre_process};    
    # change the property value. use the index selection
    $self->properties->{$id}->{selection}->(
        $value
    ) if exists $self->properties->{$id}->{selection};

    # change the property value. use the string
    $self->properties->{$id}->{string_selection}->(
        $value
    ) if exists $self->properties->{$id}->{string_selection};

    # exec the callback
    $self->properties->{$id}->{frame_callback}->($self, $ctrl, $event) if exists
        $self->properties->{$id}->{frame_callback};    
    
    $event->Skip;
}

sub OnDatePicker {
    my ( $self, $ctrl, $event ) = @_;
    
    my $id = $ctrl->GetId;

    # change the property value
    $self->properties->{$id}->{value}->(
        $event->GetDate->FormatISODate
    ) if exists $self->properties->{$id}->{value};
    # exec the callback
    $self->properties->{$id}->{frame_callback}->($self, $ctrl, $event) if exists
        $self->properties->{$id}->{frame_callback};    
    
    $event->Skip;
}


my $change_value = {
    'Wx::SpinCtrl' => sub { my ($ctrl, $value ) = @_; $ctrl->SetValue($value)},
    'Wx::TextCtrl' => sub { my ($ctrl, $value ) = @_; $ctrl->ChangeValue($value)},
    'Wx::CheckBox' => sub { my ($ctrl, $value ) = @_; $ctrl->SetValue($value)},
    'Wx::DatePickerCtrl' => sub { my ($ctrl, $value ) = @_;
                                  my $date = Wx::DateTime->new;    
                                  my ($yyyy, $mm, $dd, $hh, $mi, $ss ) = split(/[:\/\\\-\.\s]/, $value);
                                  $date->ParseDate(
                                    sprintf("%s/%s/%s", $yyyy, $mm, $dd)
                                  );
                                  $ctrl->SetValue($date);
                                },
};

my $clear_value = {
    'Wx::TextCtrl' => sub { my ($ctrl) = @_; $ctrl->Clear},
    'Wx::CheckBox' => sub { my ($ctrl) = @_; $ctrl->SetValue(0)},
    'Wx::DatePickerCtrl' => sub { my ($ctrl) = @_; $ctrl->SetValue(Wx::DateTime->new->SetToCurrent)},
};    

sub SetProperties {
    my ( $self ) = @_;
    
    map {
        my $ctrl =$self->FindWindow($_);
        if(defined $ctrl){
            # checkbox, static text
            $change_value->{ref $ctrl}->(
                $ctrl,
                $self->properties->{$_}->{value}->()
            ) if exists $self->properties->{$_}->{value};
            # only works for control with items
            $ctrl->SetSelection(
                $self->properties->{$_}->{selection}->()
            ) if exists $self->properties->{$_}->{selection};

            $ctrl->SetStringSelection(
                gettext(
                    $self->properties->{$_}->{string_selection}->()
                )
            ) if exists $self->properties->{$_}->{string_selection};
        }
    }
    keys %{$self->properties};
}

sub InitLabels {
    my ( $self ) = @_;
    
    map {
        my $ctrl =$self->FindWindow($_)||$self->{$_};
        #printf("ctrl %s : %s\n", $_, $ctrl);        
        if(defined $ctrl){
            # checkbox, static text
            $ctrl->SetLabel(
               $self->properties->{$_}->{label}
            ) if exists $self->properties->{$_}->{label};

            $ctrl->GetStaticBox->SetLabel(
                $self->properties->{$_}->{staticbox_label}
            ) if exists $self->properties->{$_}->{staticbox_label};
        
            # radiobox
            my $labels =$self->properties->{$_}->{labels};
            $labels||=[];
            for(my $i=0; $i < scalar @$labels ; $i++){
                $ctrl->SetItemLabel($i, $labels->[$i]);
            }
        }
    }
    keys %{$self->properties};

}

sub InitChoices {
    my ( $self ) = @_;

        map {
        my $ctrl =$self->FindWindow($_);
        #printf("ctrl %s : %s\n", $_, $ctrl);        
        if(defined $ctrl){
            # choice
            my $choices =$self->properties->{$_}->{choices};
            $choices||=[];
            map{
                $ctrl->Append($_);
            }@$choices;
        }
    }
    keys %{$self->properties};

}

sub GetProperties {
    my ( $self ) = @_;

    map {
        my $ctrl = $self->FindWindow($_);
        #printf("ctrl %s : %s\n", $_, $ctrl);        
        if(defined $ctrl){
        # checkbox, static text
            $self->properties->{$_}->{value}->(
                $ctrl->GetValue()
            ) if exists $self->properties->{$_}->{value};

            $self->properties->{$_}->{selection}->(
                $ctrl->GetSelection()            
            ) if exists $self->properties->{$_}->{selection};

            $self->properties->{$_}->{string_selection}->(
                $ctrl->GetStringSelection()            
            ) if exists $self->properties->{$_}->{string_selection};
        }
    }
    keys %{$self->properties};
}

sub ClearProperties {
    my ( $self ) = @_;
    
    map {
        my $ctrl =$self->FindWindow($_);
        if(defined $ctrl){
             # checkbox, static text
            $clear_value->{ref $ctrl}->(
                $ctrl
            ) if exists  $clear_value->{ref $ctrl};
            # only works for control with items
            $ctrl->SetSelection(
                -1            
            ) if exists $self->properties->{$_}->{selection};
        }

            $ctrl->SetStringSelection(
                -1            
            ) if exists $self->properties->{$_}->{string_selection};
    }
    keys %{$self->properties};

}
1;