# +-----------------------------------------------------------------------+
# | pLoader - a Perl photo uploader for Piwigo                            |
# +-----------------------------------------------------------------------+
# | Copyright(C) 2008      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 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_VIRTUAL
             wxLC_REPORT
			 wxLC_AUTOARRANGE
             wxBORDER_THEME
             wxLIST_HITTEST_ONITEM
             wxLIST_NEXT_ALL
             wxLIST_STATE_SELECTED
             wxLIST_STATE_DONTCARE
             wxLIST_STATE_FOCUSED 
			 wxIMAGE_LIST_SMALL
         /;
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,
        wxDefaultSize,
		wxNO_BORDER
    );
	
	$self->wx_img(
        Wx::ImageList->new( 16, 16, 1 )
	);
	$self->wx_img->Add(
        Wx::Bitmap->new( '../res/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}
	);
	print Dumper $self->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);
			}
		}
	);
	
	$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;
                                    $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;
}

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 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
    );	
}

1;

