# +-----------------------------------------------------------------------+
# | pLoader - a Perl photo uploader for Piwigo                            |
# +-----------------------------------------------------------------------+
# | Copyright(C) 2008-2010 Piwigo Team                  http://piwigo.org |
# +-----------------------------------------------------------------------+
# | This program is free software; you can redistribute it and/or modify  |
# | it under the terms of the GNU General Public License as published by  |
# | the Free Software Foundation                                          |
# |                                                                       |
# | This program is distributed in the hope that it will be useful, but   |
# | WITHOUT ANY WARRANTY; without even the implied warranty of            |
# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
# | General Public License for more details.                              |
# |                                                                       |
# | You should have received a copy of the GNU General Public License     |
# | along with this program; if not, write to the Free Software           |
# | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
# | USA.                                                                  |
# +-----------------------------------------------------------------------+
package Uploader::GUI::wxImageListCtrl;
use strict;
use Wx;
use Wx::DND;
use POSIX qw(ceil floor);
use Wx::Locale qw/:default/;
use Wx qw/
             wxDefaultPosition
             wxDefaultSize
             wxLC_LIST
             wxNO_BORDER
             wxLC_EDIT_LABELS
             wxLC_ICON
             wxLC_REPORT
             wxLC_SMALL_ICON
             wxIMAGE_LIST_NORMAL
             wxBITMAP_TYPE_JPEG
             wxBITMAP_TYPE_PNG
             wxBLACK
             wxLC_REPORT
             wxLIST_NEXT_ALL
             wxLIST_STATE_SELECTED
             wxLIST_STATE_DONTCARE
             wxLIST_STATE_FOCUSED 
             wxIMAGE_LIST_SMALL
             wxTheApp
             wxVERTICAL
             wxALIGN_CENTER
             wxHORIZONTAL
             wxALL
             wxGROW
             wxWHITE
             wxSWISS 
             wxNORMAL
             wxBOLD
             wxBITMAP_TYPE_PNG
         /;
use Wx::Event qw/
                    EVT_LIST_BEGIN_DRAG
                    EVT_LIST_ITEM_SELECTED
                    EVT_SIZE
                /;
         
use base qw/Wx::ListCtrl Class::Accessor::Fast/;
__PACKAGE__->mk_accessors( 
    qw/
          prevItemCount
          imagenames
          imagelist
          wx_imagelist
          image_size
          arrange_items
          styles
          insert_items
          initialize
          columns
          change_display_mode
          wx_img
          item_refresh
      / 
);
use Data::Dumper;


sub new {
    my( $class, $params ) = @_;

  
    my( $self ) = $class->SUPER::new(
        $params->{parentwnd},
        -1,
        wxDefaultPosition,
        [ -1, -1],
    );
    
    $self->wx_img(
        Wx::ImageList->new( 16, 16, 1 )
    );
    $self->wx_img->Add(
        Wx::Bitmap->new( wxTheApp->resource_path('image.png'), wxBITMAP_TYPE_PNG )    
    );

    $self->imagelist(
        $params->{imagelist}
    );
    # bitmap container for photo selection
    $self->wx_imagelist(
        $params->{wx_imagelist}||$self->imagelist->wx_thumb_imglist
    );

    $self->image_size(
        $params->{image_size}
    );

    $self->columns(
        $params->{columns}
    );

    $self->prevItemCount(-1);


    EVT_LIST_BEGIN_DRAG( $self, $self, \&OnBeginDrag);

    EVT_SIZE($self, sub {
            my ( $this, $event ) = @_;
    
            $this->arrange_items(1);
            $event->Skip();
        }
    );
    
    Wx::Event::EVT_IDLE(
        $self,
        sub {
            my ($self, $event)=@_;

            if($self->arrange_items){
                $self->Refresh; 
                $self->arrange_items(0);
            }
            if($self->change_display_mode){
                my $dm = $self->imagelist->display_mode;
                   $self->initialize->{$dm}->($self) if exists $self->initialize->{$dm};
                $self->Refresh; 
                $self->change_display_mode(0);
            }
            $event->Skip;
        }
    );

    # manages empty panel position
    Wx::Event::EVT_PAINT( $self, sub {
            my ( $self, $event ) = @_;
            if(exists $self->{_empty_panel}){
                my ($w, $h) = $self->GetSizeWH;
                my ($x, $y) = $self->GetPositionXY;
                my ($wp, $hp) = $self->{_empty_panel}->GetSizeWH;
                my $x_off = ($w-$wp)/3 > 0 ? ($w-$wp)/3 : 0;
                my $y_off = ($h-$hp)/3 > 0 ? ($h-$hp)/3 : 0;
                $self->{_empty_panel}->Move(
                    [ $x+$x_off, $y+$y_off ]
                );
            }
            $event->Skip;
        }
    );

    
    $self->initialize(
        {

            'Thumbnail' => sub {  my ( $self ) = @_;
                                $self->Freeze;
                                $self->ClearAll;
                                $self->SetSingleStyle(wxLC_ICON);
                                $self->SetSingleStyle(wxLC_EDIT_LABELS, 0);
                                $self->SetImageList( $self->wx_imagelist, wxIMAGE_LIST_NORMAL ) ;
                                $self->Thaw;
                     },            
            'Thumbnail and caption' => sub {  my ( $self ) = @_;
                                $self->Freeze;
                                $self->ClearAll;
                                $self->SetSingleStyle(wxLC_ICON);
                                $self->SetSingleStyle(wxLC_EDIT_LABELS);
                                $self->SetImageList( $self->wx_imagelist, wxIMAGE_LIST_NORMAL ) ;
                                $self->Thaw;
                     },            
             'Property list' => sub { my ( $self ) = @_;
                                my $i=0;
                                
                                $self->Freeze;
                                $self->ClearAll;
                                $self->SetSingleStyle(wxLC_REPORT);
                                $self->SetSingleStyle(wxLC_EDIT_LABELS);
                                $self->SetImageList( $self->wx_img, wxIMAGE_LIST_SMALL ) ;
                                map    {
                                    $self->InsertColumn($i, $_->{label});
                                    $i++;
                                }@{$self->columns};                                
                                $self->Thaw;
                            },
        }
    );

    $self->item_refresh(
        {
            'Thumbnail' => sub {},
            'Thumbnail and caption' => sub { my ( $self, $index ) = @_;
                                        my $image = $self->imagelist->GetImage($index);
                                        $self->SetItem(
                                            $index,
                                            0,
                                            $image->site_name,
                                        ) if defined $image;
                                    },
            'Property list' => sub { my ( $self, $index ) = @_;
                                my $col = 0;
                                my $image = $self->imagelist->GetImage($index);
                                map{
                                    $self->SetItem(
                                        $index,
                                        $col,
                                        $image->$_
                                    ) if defined $image;
                                    $self->SetColumnWidth($col, -1);
                                    $col++;
                                }
                                qw/site_name site_comment site_author file create_date/;
                            },
        }
    );
    
    $self->insert_items(
        {
            'Thumbnail' => sub { my ( $self, $index ) = @_; $self->InsertImageItem($index, $index);},
            'Thumbnail and caption' => sub { my ( $self, $index ) = @_;
                                           $self->InsertImageStringItem(
                                               $index,
                                               $self->imagelist->GetImage($index)->site_name,
                                               $index,
                                           );
                                     },
            'Property list' => sub { my ( $self, $index ) = @_;
                                       
                                $self->InsertImageStringItem(
                                    $index,
                                    "",
                                    0
                                );
                                $self->ItemRefresh($index);

                            },
        }
    );

    
    $self->initialize->{$self->imagelist->display_mode}->($self) if exists $self->initialize->{$self->imagelist->display_mode};

    $self->init_empty_msg;

    $self;
}

sub ItemRefresh {
    my ( $self, $index ) = @_;
    
    $self->item_refresh->{$self->imagelist->display_mode}->($self, $index) if exists $self->item_refresh->{$self->imagelist->display_mode};
}

sub OnBeginDrag {
  my( $self, $event ) = @_;


  my $data = Wx::TextDataObject->new( 
      Dumper $self->GetSelectedItems 
  );
  my $source = Wx::DropSource->new( $self );
  $source->SetData( $data );

  $source->DoDragDrop( 1 );
}

sub GetSelectectItemsCount {
    my ( $self ) = @_;    

    scalar @{$self->GetSelectedItems};
}

sub GetSelectedItems {
    my ( $self ) = @_;    

  # find selected items
  my $item = -1;
  my $items = [];
  while(1) {
      $item = $self->GetNextItem(
          $item,      
          wxLIST_NEXT_ALL,
          wxLIST_STATE_SELECTED
      );
      last if(-1 == $item);
      
      # item is selected    
      push @$items, $item
  }

  $items;
}

sub GetAllItems {
    my ( $self ) = @_;    

  # find selected items
  my $item = -1;
  my $items = [];
  while(1) {
      $item = $self->GetNextItem(
          $item,      
          wxLIST_NEXT_ALL,
          wxLIST_STATE_DONTCARE
      );
      last if(-1 == $item);
      
      # item is selected    
      push @$items, $item
  }
  
  $items;
    
}


sub Refresh {
    my ( $self ) = @_;    

   $self->Freeze();
   $self->DeleteAllItems;
   eval {
       my $y0 = 0;
       my $x0 = 0;

       my $x_spacing = $self->image_size + 2;
       my $y_spacing = $self->image_size + 2;
       my $ipr = floor(($self->GetClientSize->GetWidth - 0.20*$x_spacing)/$x_spacing)||1;
       for( my $i = 0 ; $i < $self->wx_imagelist->GetImageCount ; $i++){
            # call the method corresponding to the display mode
            my $indx = $self->insert_items->{$self->imagelist->display_mode}->($self, $i);
            if( 'Thumbnail' eq $self->imagelist->display_mode){
                my $row = floor($i/$ipr);
                my $col = $i%$ipr;
                $self->SetItemPosition(
                    $i,
                    Wx::Point->new(
                        $x0 + $x_spacing*$col,
                        $y0 + $y_spacing*$row,
                    ),
                );
            }
       }   
   };

   map{
       $self->SelectItem(
           $_
       );
       
       $self->EnsureVisible($_);
   } @{$self->imagelist->image_selection||[]};

   $self->Thaw();
   $self->SetFocus;
}

sub SelectItem {
    my ( $self, $index ) = @_;

    $self->SetItemState(
        $index,
        wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED,
        wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED
    );    
}

sub OnEmpty {
    my ( $self ) = @_;

    $self->_OnEmptyLayout;

}

sub OnNotEmpty {
    my ( $self ) = @_;

    $self->{_empty_panel}->Show(0) if exists $self->{_empty_panel};
}

sub _OnEmptyLayout {

    my( $self ) = @_;
    $self->{_empty_panel}->Show(1);

}

sub add_button {
    my ( $self ) = @_;

    $self->{_add_bt};
}

sub init_empty_msg {

    my ( $self ) = @_;
    # add a panel
    my $empty_panel = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize);
    my( $item0 ) = Wx::BoxSizer->new( wxVERTICAL );
    
    my $fb = Wx::Font->new( 12, wxSWISS, wxNORMAL, wxBOLD );
    my $fn = Wx::Font->new( 12, wxSWISS, wxNORMAL, wxNORMAL );

    my( $item1 ) = Wx::StaticText->new( $empty_panel, -1, gettext("Drag photos here to get started"), wxDefaultPosition, wxDefaultSize, 0 );
    $item1->SetFont($fb);
    $item0->AddWindow( $item1, 0, wxALIGN_CENTER|wxALL, 5 );

    my( $item2 ) = Wx::BoxSizer->new( wxHORIZONTAL );
    
    my( $item3 ) = Wx::StaticText->new( $empty_panel, -1, gettext("Or click"), wxDefaultPosition, wxDefaultSize, 0 );
    $item3->SetFont($fn);
    $item2->AddWindow( $item3, 0, wxALIGN_CENTER|wxALL, 5 );

    my $icon1 = Wx::Icon->new();
    eval {
        $icon1->LoadFile(
            wxTheApp->resource_path('tb_add.png'),
            wxBITMAP_TYPE_PNG
        );
    };
    my $bmp = Wx::Bitmap->new( $icon1 );

    my( $item4 ) = Wx::BitmapButton->new( $empty_panel, -1, $bmp, wxDefaultPosition, wxDefaultSize );
    $item2->AddWindow( $item4, 0, wxALIGN_CENTER|wxALL, 5 );

    my( $item5 ) = Wx::StaticText->new( $empty_panel, -1, gettext("to choose files on your computer"), wxDefaultPosition, wxDefaultSize, 0 );
    $item5->SetFont($fn);
    $item2->AddWindow( $item5, 0, wxALIGN_CENTER|wxALL, 5 );

    $item0->Add( $item2, 0, wxALIGN_CENTER|wxALL, 0 );

    $empty_panel->SetSizer( $item0 );
    $item0->SetSizeHints( $empty_panel );

    $self->{_empty_panel} = $empty_panel;
    $self->{_add_bt} = $item4;
    $self->{_empty_panel}->SetBackgroundColour(wxWHITE);

    my ($wp, $hp) = $self->{_empty_panel}->GetSizeWH;

    $self->SetMinSize( [20+$wp, -1 ]);

}



1;

