use v5.12;
use warnings;
use Wx;

package App::Harmonograph::GUI::Part::Pendulum;
use base qw/Wx::Panel/;
use App::Harmonograph::GUI::SliderCombo;

sub new {
    my ( $class, $parent, $label, $help, $on, $max,  ) = @_;
    return unless defined $max;
    my $self = $class->SUPER::new( $parent, -1);

    $self->{'name'} = $label;
    $self->{'maxf'} = $max;
    $self->{'initially_on'} = $on;

    $self->{'on'} = Wx::CheckBox->new( $self, -1, '', [-1,-1],[-1,-1], 1 );
    $self->{'on'}->SetToolTip('set partial pendulum on or off');
    
    my $lbl  = Wx::StaticText->new($self, -1, uc($label) );

    $self->{'frequency'}  = App::Harmonograph::GUI::SliderCombo->new
                        ( $self, 100, 'f', 'frequency of '.$help, 1, $max, 1 );
    $self->{'freq_dez'} = App::Harmonograph::GUI::SliderCombo->new
                        ( $self, 100, 'f dec.', 'decimals of frequency at '.$help, 0, 1000, 0);
    $self->{'invert_freq'} = Wx::CheckBox->new( $self, -1, ' Inv.');
    $self->{'invert_freq'}->SetToolTip('invert (1/x) pendulum frequency');
    $self->{'direction'} = Wx::CheckBox->new( $self, -1, ' Dir.');
    $self->{'direction'}->SetToolTip('invert pendulum direction (to counter clockwise)');
    $self->{'half_off'} = Wx::CheckBox->new( $self, -1, ' 2');
    $self->{'half_off'}->SetToolTip('pendulum starts with offset of half rotation');
    $self->{'quarter_off'} = Wx::CheckBox->new( $self, -1, ' 4');
    $self->{'quarter_off'}->SetToolTip('pendulum starts with offset of quater rotation');
    $self->{'offset'} = App::Harmonograph::GUI::SliderCombo->new
                            ($self, 110, 'Offset', 'additional offset pendulum starts with (0 - quater rotation)', 0, 100, 0);
                            
    $self->{'radius'} = App::Harmonograph::GUI::SliderCombo->new( $self, 100, 'r', 'radius of pendulum swing', 0, 150, 100);
    $self->{'damp'} = App::Harmonograph::GUI::SliderCombo->new( $self, 100, 'Damp', 'damping factor', 0, 1000, 0);


    Wx::Event::EVT_CHECKBOX( $self, $self->{'on'}, sub { $self->update_enable() });
    
    my $f_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
    $f_sizer->Add( $self->{'frequency'}, 0, &Wx::wxALIGN_LEFT|&Wx::wxGROW|&Wx::wxLEFT, 49);
    $f_sizer->Add( $self->{'freq_dez'}, 0, &Wx::wxALIGN_LEFT|&Wx::wxGROW|&Wx::wxLEFT,  11);
    $f_sizer->Add( 0, 0, &Wx::wxEXPAND | &Wx::wxGROW);
    
    my $r_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
    $r_sizer->Add( $self->{'on'},       0, &Wx::wxALIGN_LEFT|&Wx::wxALIGN_CENTER_VERTICAL|&Wx::wxGROW|&Wx::wxLEFT, 0);
    $r_sizer->Add( $lbl,                0, &Wx::wxALIGN_LEFT|&Wx::wxALIGN_CENTER_VERTICAL|&Wx::wxGROW|&Wx::wxALL, 12);
    $r_sizer->Add( $self->{'radius'},   0, &Wx::wxALIGN_LEFT|&Wx::wxGROW|&Wx::wxLEFT,  0);
    $r_sizer->Add( $self->{'damp'},     0, &Wx::wxALIGN_LEFT|&Wx::wxGROW|&Wx::wxLEFT,  0);
    $r_sizer->Add( 0, 0, &Wx::wxEXPAND | &Wx::wxGROW);
    
    my $o_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
    $o_sizer->Add( $self->{'invert_freq'}, 0, &Wx::wxALIGN_LEFT|&Wx::wxALIGN_CENTER_VERTICAL|&Wx::wxGROW|&Wx::wxLEFT, 86);
    $o_sizer->Add( $self->{'direction'},   0, &Wx::wxALIGN_LEFT|&Wx::wxALIGN_CENTER_VERTICAL|&Wx::wxGROW|&Wx::wxLEFT, 20);
    $o_sizer->Add( $self->{'half_off'},    0, &Wx::wxALIGN_LEFT|&Wx::wxALIGN_CENTER_VERTICAL|&Wx::wxGROW|&Wx::wxLEFT, 20);
    $o_sizer->Add( $self->{'quarter_off'}, 0, &Wx::wxALIGN_LEFT|&Wx::wxALIGN_CENTER_VERTICAL|&Wx::wxGROW|&Wx::wxLEFT,  8);
    $o_sizer->Add( $self->{'offset'},      0, &Wx::wxALIGN_LEFT|&Wx::wxALIGN_CENTER_VERTICAL|&Wx::wxGROW|&Wx::wxLEFT,  0);
    $o_sizer->Add( 0, 0, &Wx::wxEXPAND | &Wx::wxGROW);
    
    my $sizer = Wx::BoxSizer->new(&Wx::wxVERTICAL);
    $sizer->Add( $r_sizer,  0, &Wx::wxALIGN_LEFT|&Wx::wxGROW, 0);
    $sizer->Add( $f_sizer,  0, &Wx::wxALIGN_LEFT|&Wx::wxGROW, 0);
    $sizer->Add( $o_sizer,  0, &Wx::wxALIGN_LEFT|&Wx::wxGROW, 0);
    $self->SetSizer($sizer);

    $self->init();
    $self;
}

sub init {
    my ( $self ) = @_;
    $self->set_data ({ on => $self->{'initially_on'}, radius => 1, frequency => 1, offset => 0, damp => 0} );
}

sub get_data {
    my ( $self ) = @_;
    my $f = $self->{'frequency'}->GetValue + $self->{'freq_dez'}->GetValue/1000;
    $f = 1 / $f if $self->{ 'invert_freq' }->IsChecked;
    $f =    -$f if $self->{ 'direction' }->IsChecked;
    {
        on        => $self->{ 'on' }->IsChecked ? 1 : 0,
        frequency => $f,
        offset    => (0.5 * $self->{'half_off'}->IsChecked) 
                   + (0.25 * $self->{'quarter_off'}->IsChecked) 
                   + ($self->{'offset'}->GetValue / 400),
        radius    => $self->{'radius'}->GetValue / 100,
        damp      => $self->{'damp'}->GetValue,
    }
}

sub set_data {
    my ( $self, $data ) = @_;
    return unless ref $data eq 'HASH' and exists $data->{'frequency'}
        and exists $data->{'offset'} and exists $data->{'radius'} and exists $data->{'damp'};
    $self->{ 'data'} = $data;
    $self->{ 'on' }->SetValue( $data->{'on'} );
    $self->{ 'direction' }->SetValue( $data->{'frequency'} < 0 );
    $data->{ 'frequency'} = abs $data->{'frequency'};
    $self->{ 'invert_freq' }->SetValue( $data->{'frequency'} < 1 );
    $data->{ 'frequency'} = 1 / $data->{'frequency'} if $data->{'frequency'} < 1;
    $self->{ 'frequency' }->SetValue( int $data->{'frequency'} );
    $self->{ 'freq_dez' }->SetValue( int( 1000 * ($data->{'frequency'} - int $data->{'frequency'} ) ) );
    $self->{ 'half_off' }->SetValue( $data->{'offset'} >= 0.5 );
    $data->{ 'offset' } -= 0.5 if $data->{'offset'} >= 0.5;
    $self->{ 'quarter_off' }->SetValue( $data->{'offset'} >= 0.25 );
    $data->{ 'offset' } -= 0.25 if $data->{'offset'} >= 0.25;
    $self->{'offset'}->SetValue( int( $data->{'offset'} * 400 ));
    $self->{ 'radius' }->SetValue( $data->{'radius'} * 100 );
    $self->{ 'damp' }->SetValue( $data->{'damp'} );
    $self->update_enable;
    1;
}

sub update_enable {
    my ($self) = @_;
    my $val = $self->{ 'on' }->IsChecked;
    $self->{$_}->Enable( $val ) for qw/frequency freq_dez invert_freq direction half_off quarter_off offset radius damp/;
}


1;
