package Handy::Dandy;
use strict;
use vars qw( $ATL $AUTOLOAD );
use Exporter;
use OOorNO qw( :all );
use Handy::Dandy::TimeTools qw( :all );
$Handy::Dandy::VERSION     = 1.30_4;               # 9/23/02, 2:30 pm
@Handy::Dandy::ISA         = qw( Exporter OOorNO Handy::Dandy::TimeTools );
@Handy::Dandy::EXPORT_OK   =
   (
      @OOorNO::EXPORT_OK,
      @Handy::Dandy::TimeTools::EXPORT_OK, qw
      (
         utf8   html_escape   convert_size   isin   touch
         use_once   isnum   trim
      )
   );
%Handy::Dandy::EXPORT_TAGS =
   (
      'HandyDandy' => [ @Handy::Dandy::EXPORT_OK ],
      'OOorNO'     => [ @OOorNO::EXPORT_OK ],
      'TimeTools'  => [ @Handy::Dandy::TimeTools::EXPORT_OK ],
      'all'        =>
         [
            @Handy::Dandy::EXPORT_OK,
            @OOorNO::EXPORT_OK,
            @Handy::Dandy::TimeTools::EXPORT_OK
         ],
   );



=pod

   AUTHOR
      Tommy Butler <tommy @ atrixnet.com>
      phone: (817)-468-7716
      6711 Forest Park Dr
      Arlington, TX
           76001-8403

   COPYRIGHT   Tommy Butler. All rights reserved
   LISCENCE    This software is free, use/distribute under the GNU GPL.
   BUGS TO     Tommy Butler <perlmod @ atrixnet.com>

   HISTORY
      1.30_4
         9/23/02, 2:30 pm
         Fixed 'deep recursion' problem in AUTOLOAD

      1.30_3
         Method 'isnum' now handles negative numbers

      1.30_4
         Export tag ':all' now exports from OOorNO and
         Handy::Dandy::TimeTools as it should have before.
         New export tag ':HandyDandy' added; it exports native methods only.

=cut


# --------------------------------------------------------
# Constructor
# --------------------------------------------------------
sub new { bless({}, shift(@_)); }


# --------------------------------------------------------
# Handy::Dandy::use_once
# --------------------------------------------------------
sub use_once {}


# --------------------------------------------------------
# Handy::Dandy::isnum
# --------------------------------------------------------
sub isnum { isint(@_) || isfloat(@_); }


# --------------------------------------------------------
# Handy::Dandy::isint
# --------------------------------------------------------
sub isint {

   my($check)  = myargs(@_);

   return(undef) unless (defined($check));

   $check =~ s/(^\-)//o;

   # it's too complicated to figure out whether or not a given
   # string is an integer when it contains the '_' character.
   # sometimes it is, almost always it isn't.  I'm not going to
   # write in support for it.  calls that pass the "_" character
   # to this method will get a value of undef passed back
   return(undef) if $check =~ tr/0123456789/0123456789/cd >= 1;

   (length($check)) ?  ($1||'') . $check : undef;
}


# --------------------------------------------------------
# Handy::Dandy::isfloat
# --------------------------------------------------------
sub isfloat {

   my($check)  = myargs(@_);

   return(undef) unless (defined($check));

   $check =~ s/(^\-)//o;

   return(undef) if $check !~ /\./;
   return(undef) if substr($check,-1,1) eq '.';
   return(undef) if $check =~ tr/././d > 1;
   return(undef) if $check =~ tr/._0123456789/._0123456789/cd >= 1;

   (length($check)) ?  ($1||'') . $check : undef;
}


# --------------------------------------------------------
# Handy::Dandy::html_escape()
# --------------------------------------------------------
sub html_escape {

   my(@chars) = split(//,(${\myargs(@_)}||return(undef)));

   my($c) = ''; my($i) = 0;

   # need to escape ascii 33-47, 58-64, 91-96, 123+
   for ($i = 0; $i < @chars; ++$i) {

      $c = ord($chars[$i]);

      if
         (
            ($c > 32 and $c < 48)
               ||
            ($c > 57 and $c < 65)
               ||
            ($c > 90 and $c < 97)
               ||
            ($c > 123)
         )
      { $chars[$i] = qq[\046\043] . $c . qq[\073]; }
   }

   return(join('',@chars));
}


# --------------------------------------------------------
# Handy::Dandy::AUTOLOAD()
# --------------------------------------------------------
sub AUTOLOAD {

   my($sub) = $AUTOLOAD; $sub =~ s/^.*\:\://o;

   if (ref($ATL) ne 'HASH') { $ATL = eval($ATL); }

   if (ref(eval(qq[\$sub])) eq 'CODE') { goto &$sub; }

   unless ($ATL->{ $sub }) {

      die(qq[BAD AUTOLOAD. Can't do $sub().  Don't know what it is.]);
   }

   eval($ATL->{ $sub }); CORE::delete($ATL->{ $sub });

   goto &$sub;
}


# --------------------------------------------------------
# Handy::Dandy::DESTROY()
# --------------------------------------------------------
sub DESTROY {}


INIT { $ATL = <<'___AUTOLOADED___'; }
   {
'touch' => <<'__SUB__',
# --------------------------------------------------------
# Handy::Dandy::touch
# --------------------------------------------------------
sub touch {

   my(@items)  = myargs(@_);

   foreach(@items) {

      if    (ref($_) eq 'SCALAR') { $$_ = '' if (not defined($$_)); }
      elsif (ref($_) eq 'HASH')   { %$_ = {} if (not defined(%$_)); }
      elsif (ref($_) eq 'ARRAY')  { @$_ = [] if (not defined(@$_)); }
   }

   return(@items);
}
__SUB__

'isin' => <<'__SUB__',
# --------------------------------------------------------
# Handy::Dandy::isin
# --------------------------------------------------------
sub isin {

   my(@list)   = myargs(@_);
   my($cmp)    = shift(@list) || return(undef);

   for (my($i) = 0; $i < @list; ++$i) {

      $list[$i] = '' unless defined($list[$i]);

      if ($list[$i] eq $cmp) { return($list[$i],$i) }
   }

   '';
}
__SUB__

'trim' => <<'__SUB__',
# --------------------------------------------------------
# Handy::Dandy::trim()
# --------------------------------------------------------
sub trim { print('foo');

   my($str,$len,$lst) = myargs(@_);

   $str = (defined($str)) ? $str : '';
   $len = (defined($len)) ? $len : 0;
   $lst = (defined($lst)) ? $lst : 0;

   return('') unless ($str and $len);

   if ((length($str)==0) or (length($len)==0)) {

      return($str);
   }

   $len = int($len);

   if (length($str) <= $len) {

      return($str);
   }

   my($frag) = '';

   $frag =
      join
         (
            '',
            splice
               (
                  @{[split(//,$str)]},
                  $len
               ),
         );

   $str =
      sprintf
         (
            '%'.$len.'.'.$len.'s',
            $str
         );

   return (wantarray or $lst) ? ($str,$frag) : $str;
}
__SUB__

'convert_size' => <<'__SUB__',
# --------------------------------------------------------
# Handy::Dandy::convert_size()
# --------------------------------------------------------
sub convert_size {

   # syntax: $dandy->convert_size($int, q[bytes to megabytes])

   my($amt, $cmd) = myargs(@_);

   return(undef) unless isnum($amt);

   my(@specs)     = split(/ /,$cmd);
   my($from)      = $specs[0];
   my($to)        = $specs[-1];

   my($b) = 1;
   my($k) = 1000;
   my($m) = 1000000;

   # FROM conversions
   if ($from =~ /^ki/io) {

      $amt *= $k;
   }
   elsif ($from =~ /^meg/io) {

      $amt *= $m;
   }
   elsif ($from =~ /^by/io) {

      $amt *= $b;
   }

   # TO conversions
   if ($to =~ /^ki/io) {

      $amt /= $k;
   }
   elsif ($to =~ /^meg/io) {

      $amt /= $m;
   }
   elsif ($to =~ /^by/io) {

      $amt /= $b;
   }

   return($amt);
}
   }
__SUB__

'utf8' => <<'__SUB__',
# --------------------------------------------------------
# Handy::Dandy::utf8()
# --------------------------------------------------------
sub utf8 {

   my($toencode)  = join('',@{[&myargs,'']});
   my($no_encode) = q[a-zA-Z 0-9_\\-@.=];

   $toencode =~ s/([^&;$no_encode])/sprintf('%%%02X',ord($1))/ego;
   $toencode =~ tr/ /+/;

   return($toencode);
}
__SUB__

'html_encode' => <<'__SUB__',
# --------------------------------------------------------
# Handy::Dandy::html_encode()
# --------------------------------------------------------
sub html_encode {

   my(@chars)  = split(//,join('',@{[&myargs,'']}));

   foreach (@chars) {

      $_ = '&#' . ord($_) .';';
   }

   return(join('',@chars));
}

__SUB__
   }
___AUTOLOADED___

# --------------------------------------------------------
# end Handy::Dandy Class, return true on import
# --------------------------------------------------------

1;