#!/usr/bin/perl -w

# $Id: pixmaped,v 1.52 1999/03/07 11:14:19 root Exp $

# Copyright (c) Mark Summerfield 1999. All Rights Reserved.
# May be used/distributed under the same terms as Perl.

# TODO See "TODO.html". 

use strict ;

use Tk ;
use Tk::FileSelect ;
#use Tk::Clipboard ;
use Tk::MesgBox ;
use Tk::ColourChooser ;
use File::Basename ;
use Cwd ;

use FindBin qw( $RealBin ) ;
use lib $RealBin ;


use vars qw( $VERSION 
             %Global %Const %Opt 
             $Win 
             %Image  %Grid  %Button  $MenuFile  @Undo  %Modules
         ) ; 

$VERSION = '1.10' ; # Application version.

my $DieOnWarn      = 0 ;
my $WarnInDialogue = 0 ;


&initialise ;

MainLoop ;


sub initialise {

    $Win = MainWindow->new() ;
    $Win->title( "Loading  Pixmaped..." ) ; 
    &cursor( 1, 'watch' ) ;
    $Win->protocol( "WM_DELETE_WINDOW", \&file::quit ) ;

    &load_library( "pixmaped-globals.pl" ) ;
    &load_library( "pixmaped-consts.pl" ) ;
    &load_library( "pixmaped-opts.pl" ) ; # Default.
    &read_opts ;                          # User.
    &set_consts ;                         # Need opts to set these.
    # Ordered to make loading appear to be as fast as possible.
    &load_library( "pixmaped-menu.pl" ) ;
    &load_library( "pixmaped-buttons.pl" ) ;
    &load_library( "pixmaped-grid.pl" ) ;
    &load_library( "pixmaped-button-commands.pl" ) ;
    &load_library( "pixmaped-grid-commands.pl" ) ;
    $Win->update ; # This is the earliest we can update the main window.
    &load_library( "pixmaped-keys.pl" ) ;
    &load_library( "pixmaped-file-commands.pl" ) ;
    &load_library( "pixmaped-edit-commands.pl" ) ;
    &load_library( "pixmaped-image-commands.pl" ) ;
    &load_library( "pixmaped-help-commands.pl" ) ;
    &load_library( "pixmaped-resize.pl" ) ;
    &load_library( "pixmaped-shapes.pl" ) ;
    &load_library( "pixmaped-options.pl" ) ;
    &load_library( "pixmaped-xpm.pl" ) ;
    # We can't assume the user has GD.pm or Image::Magick.
    $Modules{GD}   = &load_optional_library( 'GD.pm', "pixmaped-gif.pl" ) ;
    $Modules{MIFF} = &load_optional_library( 
                        'Image/Magick.pm', "pixmaped-imagemagick.pl" ) ;

    $Win->CmdLine() ;
    $Button{WIDGET}{GRAB_COLOUR}->invoke ;
    $Button{WIDGET}{PENCIL}->invoke ;
    &file::new( 1 ) ;
    $Win->packPropagate( 0 ) ;
    &cursor( -1 ) ;
}


BEGIN {
    $SIG{__WARN__} = sub {
        if( $WarnInDialogue and defined $Win ) {
            &cursor( 1, 'clock' ) ;

            my $msg = $Win->MesgBox(
                            -title => "Pixmaped Error",
                            -text  => $_[0],
                            -icon  => 'ERROR',
                            ) ;
            $msg->Show ;

            &cursor( -1 ) ;
        }
        else {
            print STDOUT join( "\n", @_ ), "\n" ;
        }
    } ;
}


sub cursor {
    # lock  1 = lock and change; 
    # lock  0 = change unless locked; 
    # lock -1 = unlock and change if no locks left.

    my $lock   = shift ; 
    my $cursor = shift || $Global{ACTIVE_TOOL} ;

    $Global{CURSOR_LOCK} += $lock ;

    $Win->configure( -cursor => $cursor ) 
    if ( $lock == 1 and $Global{CURSOR_LOCK} > 0 ) or 
       ( $lock <= 0 and $Global{CURSOR_LOCK} == 0 ) ;
}


sub message {
    my( $type, $title, $text ) = @_ ;

    if( defined $Win ) {
        my $msg = $Win->MesgBox(
                        -title => "Pixmaped $title $type",
                        -text  => "$text.",
                        -icon  => uc $type,
                        ) ;
        $msg->Show ;
    }
    else {
        print STDOUT "$title $type: $text.\n" ; 
    }
}


sub read_opts {

    return unless -e $Const{OPTS_FILE} ;

    if( open( IN, $Const{OPTS_FILE} ) ) {
        local $_ ;
        while( <IN> ) {
            next if /^#/o or /^\s*$/o ;
            chomp ;
            my( $key, $val ) = /^([^\s:]+)\s*:\s*(.*)/o ;
            $val = $1 if $val =~ /([^#]+)#/o ;
            $val =~ s/\s+$//o ;
            $Opt{uc $key} = $val ;
        }
        close IN ;
        &opts_check ;
    }
    else {
        warn "Failed to read $Const{OPTS_FILE}: $!.\n" ;
    }
}


sub write_opts {

    if( open( OUT, ">$Const{OPTS_FILE}" ) ) {
        local $_ ;
        foreach ( sort keys %Opt ) {
            print OUT "$_: $Opt{$_}\n" ;
        }
        close OUT ;
        $Global{WROTE_OPTS} = 1 ;
    }
    else {
        warn "Failed to write $Const{OPTS_FILE}: $!.\n" ;
    }
}


sub set_consts {
    # No dependencies.
}


sub abs_path {
    my $path = shift ;

    my $filename = basename( $path ) ;

    $path        = dirname( $path ) ;
    chdir $path ;
    $path = cwd ;

    $path =~ s!/./!/!go ;

    if( $filename ) {
        $path .= '/' unless substr( $path, -1, 1 ) eq '/' ;
        $path .= $filename ;
    }

    $path ;
}


sub load_library {
    my $file = shift ;
    
    unless( my $return = do "${file}" ) {
        my $warned = 0 ;
        warn "Failed to parse $file: $@.\n", 
            $warned = 1 if $@ ;
        warn "Failed to do $file: $!\n",     
            $warned = 1 if not $warned and not defined $return ;
        warn "Failed to run $file.\n",       
            $warned = 1 if not $warned and $return ;
        die "Failed to load $file.\n" if $DieOnWarn ;
    }
}


sub load_optional_library {

    my( $libname, $filename ) = @_ ;

    my $fakefilename = $filename ;
    $fakefilename =~ s/\.pl$/-fake.pl/o ;

    my $loaded = 1 ;
    eval {
        require $libname ;
    } ;
    $loaded = 0 if $@ ; 

    if( $loaded ) {
        &load_library( $filename ) ;
    }
    else {
        &load_library( $fakefilename ) ;
    }

    $loaded ;
}


__END__

