#!/usr/bin/perl -w
#
# 03/25/01 - Slide_Show
# Author: Thomas Ballard (thomas@esqsoft.com)
# Note: Comments and Suggestions would be appreciated.
#





##################################################################################################
### GLOBALS AND INCLUDES
### 

  use strict;
  use O::CGI qw(GET_FORM CONTENT_TYPE);
  use O::conf_util qw(conf_read conf_write);
  use O::ENCODE qw(URLDecode URLEncode URL_ENCODE);
  use O::FILE_UTIL qw(compute_used);
  use O::FORMS qw(GET_HIDDEN);
  use O::Is qw(isun);
  use O::Partner;
  use O::results2html;
  use O::s2dr qw(s2dr);
  use O::SlideShow qw(list_shows delete_show list_pictures);
  use O::Slappy qw(slap make_headers);
  use O::User;
  use O::Wrap qw(wrap);
  use Image::Magick;
  use File::Copy;
  &O::Is::unbuffer;

  use O::UserAuth qw(RequireUserLogin);   
  RequireUserLogin(); 

  use O::ServiceAuth qw(requireServiceAuth);
  requireServiceAuth('slide_show_manage');


  my $partner           = new O::Partner($ENV{HTTP_HOST});
  my %SHOWS             = ();
  my $step              = "manage_shows";          #default non-wizard starting page
  my $max_pics          = 50;
  my %FORM              = GET_FORM;
    # Encountered a problem where the data in the FORM hash was NOT getting URL Decoded, so force it here
    $FORM{font_1}       = URLDecode($FORM{font_1})        if (exists $FORM{font_1});
    $FORM{font_2}       = URLDecode($FORM{font_2})        if (exists $FORM{font_2});
    $FORM{font_3}       = URLDecode($FORM{font_3})        if (exists $FORM{font_3});
    $FORM{navbar_html}  = URLDecode($FORM{navbar_html})   if exists $FORM{navbar_html};






##################################################################################################
### PRE-PROCESSING ...UM, PROCESSING (Anything that might cause us to not need to process the form data further)
### 

  ### Warn if browser isn't compatible
    # Note: some people think that browser support should be assumed carrying forward, but any reasonable person
    # knows that new software poses new problems... when new browsers are released they need to be tested and 
    # added to this check.
  my $browser_ok = '';
  $browser_ok = $ENV{HTTP_USER_AGENT} =~ /MSIE 5/       if(!$browser_ok);
  $browser_ok = $ENV{HTTP_USER_AGENT} =~ /MSIE 6/       if(!$browser_ok);
  if(!$browser_ok){
    my $temp=URL_ENCODE($ENV{HTTP_USER_AGENT});
    $temp =~ s/\+/\%20/g;
    $FORM{bad_browser_warning}   =  "^warning.header^^warning.start;warningheading=Warning:^^errortext.bad_browser_warning^";
    $FORM{bad_browser_warning}  .=  "<BR>^warning.link;linktext=errortext.click_here;url=http://microsoft.com/windows/ie/default.htm;target=_blank;onclick=return;^&nbsp;^errortext.download_here^";
    #$FORM{bad_browser_warning}  .=  "<BR>^warning.link;linktext=errortext.click_here;onclick=return;target=_self;url=/cgi-bin/feedback?option=bug_report&site=$ENV{HTTP_HOST}&category=Compatibility&link=/cgi-bin/util/slide_show_manage&question=Slide%20Show%20warning%20occured%20with%20" . $temp . ";^&nbsp;^errortext.report_problem^";
    $FORM{bad_browser_warning}  .=  "^warning.end^^warning.footer^";
  }

  ### Determine if this is the first visit this browser session
  if(!$FORM{next_page}){
    &determine_wizard;
  }
  ### Set initial navigation in case an error occurs during processing
  if($FORM{current_page}){
    $step = $FORM{current_page};
  }

  ### If we plan on leaving do it now 
	#
	# Note: If you do a location bounce to a relative link ie. /cgi-bin/util/my_member_area, then the address in the address bar doesn't
	# change, even though the bounce works.  So, if you want the location bar to change you need to bounce to an absolute URL as below.
	#
  if($FORM{next_page} =~ m%^/cgi-bin/util/my_member_area$%i){
    print "Location: http://$ENV{HTTP_HOST}/cgi-bin/util/my_member_area\n\n";
    exit;
  }
  if($FORM{next_page} =~ m%^/cgi-bin/util/sitebuilder$%i){
    print "Location: http://$ENV{HTTP_HOST}/cgi-bin/util/sitebuilder\n\n";
    exit;
  }
  if($FORM{next_page} =~ m%^/cgi-bin/util/slide_show_manage$%i){
    print "Location: http://$ENV{HTTP_HOST}/cgi-bin/util/slide_show_manage\n\n"; #force reload please
    exit;
  }





##################################################################################################
### TASK ORIENTED PROCESSING (Non-page dependent)
### 

  $FORM{from_manage} = "1"  if(not exists $FORM{from_slide_show_page});  # for w_intro.htm, puts on a wrapper or not.

  if($FORM{temp_slide_show_name}){
    &validate_slide_show_name;
  }

  if($FORM{upload_images}){
    &upload_images;
  }

  if($FORM{store_image_urls}){
    #Note: We need to resolve a number of "total_images" at this point (put it into $FORM{total_images}).
    &store_image_urls;
    delete $FORM{store_image_urls};
  }

  if($FORM{store_list_order}){
    &sort_images_in_conf;
  }

  if($FORM{create_thumbnails}){  
    &create_thumbnails;
  }

  if($FORM{sitebuilder_start_with}){
    &starts_with_value("write");
  }






##################################################################################################
### PAGE ORIENTED PROCESSING (Page dependent)
### 

  if(
    ($FORM{current_page}) && 
    ($FORM{current_page} eq 'edit_table')
    ){
    &store_edit_table_values;
  }

  if(
    ($FORM{current_page}) && 
    ($FORM{current_page} eq 'sitebuilder')
    ){
    &store_sitebuilder_value;
  }

  if($FORM{next_page} eq 'delete_one_slide_show'){
    &delete_one_slide_show;
  }

  if($FORM{next_page} eq 'delete_all_my_slide_shows'){
    &delete_all_slide_shows;
  }

  if(
    ($FORM{next_page}) && 
    ($FORM{next_page} eq 'image_order')
    ){
    my %TEMP_HASH = &prep_image_order;
    $FORM{images_option_list} = $TEMP_HASH{images_option_list};
  }

  if(
    ($FORM{current_page}) && 
    ($FORM{current_page} eq 'w_settings')
    ){
    &store_settings_data;
  }

  if(
    ($FORM{next_page}) && 
    (($FORM{next_page} eq 'w_sb_success') ||
    ($FORM{next_page} eq 'w_success') ||
    ($FORM{next_page} eq 'w_sb_code') ||
    ($FORM{next_page} eq 'image_order_success') ||
    ($FORM{next_page} eq 'w_cut_code')
    )){
    &get_slide_show_url;
		&check_site_for_slide_show_html;
  }

  if(
    ($FORM{next_page}) && 
    ($FORM{next_page} eq 'upload_images')
    ){
    if($ENV{HTTP_USER_AGENT} !~ /MSIE 5.5/){
      $FORM{upload_image_rows}     =  "^form.total_images?slide_show_manage.ie50_upload_image_row * form.total_images:slide_show_manage.ie50_upload_image_row * 10;^";
    }
    else{
      $FORM{upload_image_rows}     =  "^form.total_images?slide_show_manage.upload_image_row * form.total_images:slide_show_manage.upload_image_row * 10;^";
    }
  }

  if(
    ($FORM{current_page} && (($FORM{current_page} eq 'upload_images') || (($FORM{current_page} eq 'w_images') && $FORM{error}))) ||
    ($FORM{next_page} && ($FORM{next_page} eq 'w_images'))
    ){
    &build_image_drop_down;

    if($FORM{error}){
      # If an error during uploading or storing images occured we want to display 
      # all of the slides since the error's could span sets of 10 images.
      $FORM{start_counter_value}  = "1";
      $FORM{show_records}         = "$max_pics";
    }

    if(!$FORM{start_counter_value}){
      $FORM{start_counter_value} = "1";
    }
    $FORM{start_counter} = "^counters.c1.alt=" . $FORM{start_counter_value} . "^";
    if(!$FORM{show_records}){
      $FORM{show_records} = "10";
    }

    if($ENV{HTTP_USER_AGENT} !~ /MSIE/){
      $FORM{bad_browser_warning}   =  "^warning.header^^warning.start;warningheading=Warning:^^errortext.bad_browser_warning2^";
      $FORM{bad_browser_warning}  .=  "<BR>^warning.link;linktext=errortext.click_here;url=http://microsoft.com/windows/ie/default.htm;target=_blank;onclick=return;^&nbsp;^errortext.download_here^";
      $FORM{bad_browser_warning}  .=  "^warning.end^^warning.footer^";
    }

    if($ENV{HTTP_USER_AGENT} !~ /MSIE 5.5/){
      $FORM{generate_rows}         =  "^slide_show_manage.ie50_image_select * " . $FORM{show_records} . "^";
    }
    else{
      $FORM{generate_rows} = "^slide_show_manage.image_select * " . $FORM{show_records} . "^";
      $FORM{loading_notice_off}    =  "loading_notice('off','^this.cindex^');";
    }

    if(
      ($FORM{start_counter_value}) &&
      ($FORM{start_counter_value} > 1)
      ){

      $FORM{previous_images_link} = qq|
      <A HREF="#" 
        ONCLICK="
          var new_value=(parseInt(document.SLIDESHOW.start_counter_value.value))-10;
          if(new_value>0){ document.SLIDESHOW.start_counter_value.value=new_value; }
          else{ return false; }
          if(submitting.length<1){
            var that=document.SLIDESHOW.magic_button;
            submitting=that.value;
            that.value='^buttontxt.loading^';
            if(document.all){ that.style.backgroundColor='EE2222'; that.style.color='FFFFFF';}
            setTimeout('restore_me();',120000);
            if(navigator.appVersion.indexOf('MSIE 5')!=-1){
              window.showModelessDialog('/cgi-bin/show_me?page=slide_show_manage/uploading_takes_time.htm&wrap=1','','dialogHeight:200px;dialogWidth:400px;edge:Raised;center:Yes;help:No;resizable:No;status:No;Scroll:No;');
            }
            if(!document.SLIDESHOW.edit_next){
              document.SLIDESHOW.cstm_1.value='^form.edit_next^';
              if(document.SLIDESHOW.cstm_1.value.length>0) document.SLIDESHOW.cstm_1.name='edit_next';
            }
            document.SLIDESHOW.show_records.value='10';
            if(document.SLIDESHOW.edit_next){ document.SLIDESHOW.non_wizard_next.value='w_images'; }
            validate_form(document.SLIDESHOW,'w_images','w_images');
            return false;
          }">^sectiontext.text;text=pass.text^</A> 
      |;
    }
    else{
      $FORM{previous_images_link} = "^sectiontext.text;text=pass.text^";
    }
    if(
      ($FORM{start_counter_value}) &&
      ($FORM{start_counter_value} < ($max_pics-10))
      ){
      $FORM{next_images_link} = qq|
      <A HREF="#" 
        ONCLICK="
          var new_value=(parseInt(document.SLIDESHOW.start_counter_value.value))+10;
          if(new_value<max_slides_pos) document.SLIDESHOW.start_counter_value.value=new_value;
          else return false;
          if(submitting.length<1){
            var that=document.SLIDESHOW.magic_button;
            submitting=that.value;
            that.value='^buttontxt.loading^';
            if(document.all){ that.style.backgroundColor='EE2222'; that.style.color='FFFFFF';}
            setTimeout('restore_me();',120000);
            if(navigator.appVersion.indexOf('MSIE 5')!=-1){
              window.showModelessDialog('/cgi-bin/show_me?page=slide_show_manage/uploading_takes_time.htm&wrap=1','','dialogHeight:200px;dialogWidth:400px;edge:Raised;center:Yes;help:No;resizable:No;status:No;Scroll:No;');
            }
            if(!document.SLIDESHOW.edit_next){
              document.SLIDESHOW.cstm_1.value='^form.edit_next^';
              if(document.SLIDESHOW.cstm_1.value.length>0) document.SLIDESHOW.cstm_1.name='edit_next';
            }
            document.SLIDESHOW.show_records.value='10';
            if(document.SLIDESHOW.edit_next){ document.SLIDESHOW.non_wizard_next.value='w_images'; }
            validate_form(document.SLIDESHOW,'w_images','w_images');
            return false;
          }">^sectiontext.text;text=pass.text^</A> 
      |;
    }
    else{
      $FORM{next_images_link} = "^sectiontext.text;text=pass.text^";
    }
  }




##################################################################################################
### NAVIGATION/OUTPUT
### 

  if(
    ($FORM{sitebuilder})&&
    ($FORM{sitebuilder} eq '1')
    ){
      $FORM{show_sitebuilder} = 'true';
      #javascript tests for this key on the client end so it CAN'T exist AT ALL or its "TRUE".
  }

  if(
    (!$FORM{error}) && 
    (!$FORM{inline_error})
    ){
    delete $FORM{current_page};
    $FORM{current_page} = $FORM{next_page};
    $step = $FORM{next_page}; 
    delete $FORM{next_page};
  }
  else{
    if(
      ($FORM{current_page}) && 
      ($FORM{current_page} eq 'w_images')
      ){
      &build_image_drop_down;
    }
    $FORM{error} = URLDecode($FORM{error});
  }

  if($FORM{produce_sitewide_image_list}){
    &build_image_drop_down;
    $step="filelist_only";
  }

  if(
    ($step) && 
    ($step eq 'manage_shows')
    ){
    %SHOWS = &list_shows;
    &tell_disk_usage;
  }


  ### Specify which items must persist from page to page.
  my %NFORM = ();
  $NFORM{current_page}      = $FORM{current_page}             if exists $FORM{current_page};
  $NFORM{slide_show_path}   = $FORM{slide_show_path}          if exists $FORM{slide_show_path};
  $NFORM{total_images}      = $FORM{total_images}             if exists $FORM{total_images};
  $NFORM{sitebuilder}       = $FORM{sitebuilder}              if(exists $FORM{sitebuilder} && $FORM{sitebuilder} eq '1');
  $NFORM{slide_show_url}    = $FORM{slide_show_url}           if exists $FORM{slide_show_url};
  $NFORM{slide_show_name}   = $FORM{slide_show_name}          if exists $FORM{slide_show_name};
  $NFORM{wizard}            = $FORM{wizard}                   if exists $FORM{wizard};
  $NFORM{edit_next}         = $FORM{edit_next}                if exists $FORM{edit_next};
  $NFORM{prev_page}         = $FORM{prev_page}                if exists $FORM{prev_page};  #this is for IE since it won't allow javascript back with expired form data.
  $NFORM{total_slide_shows} = $FORM{total_slide_shows}        if exists $FORM{total_slide_shows};
  $FORM{hidden}             = GET_HIDDEN(\%NFORM, $partner->{content});



  my %FILL_HASH = ();
  if($FORM{slide_show_path}){      
    %FILL_HASH = &read_raw_form_from_conf;
    delete $FILL_HASH{sitebuilder_start_with}     if exists $FILL_HASH{sitebuilder_start_with};
    $partner->{fill} = \%FILL_HASH;

    $FORM{font_size} = $FILL_HASH{font_size}      if($FILL_HASH{font_size});
    if(
      ($FILL_HASH{disable_mouseovers}) && 
      ($FILL_HASH{disable_mouseovers} eq 'true')
      ){
      $FORM{edit_toggle} = "0";
    }
    else{
      $FORM{edit_toggle} = "1";
    }
  }

  $FORM{maximum_slides_possible} = $max_pics;   # Needed by /content/slide_show_manage/w_images.htm



  # ----------------------------------------------------------------------------------------------
  # Note, the following is in sequence here since it's dependent on data read from the conf for the FILL_HASH

  if(
    ($step) && 
    ($step eq 'w_settings')
    ){
    # Read the slide_show.conf file to for a default show setting.
    $FORM{default_slide_show_name}          = starts_with_value("read");

    ### Construct the elements needed on the w_settings page

    my $sitebuilder_settings                = &read_sitebuilder_value;
    if(
      ($sitebuilder_settings->{default_slide_show}) && 
      ($sitebuilder_settings->{default_slide_show} eq $FORM{slide_show_path})
      ){
      $FORM{current_starting_show}          = " CHECKED";
    }
    else{
      $FORM{current_starting_show}          = undef;
    }
    
    $FORM{thumbnail_button_html}            = "^w_settings_tables.thumbnail_button_html^";
    $FORM{thumbnail_text_html}              = "^w_settings_tables.thumbnail_text_html^";
    if(
      (!$FILL_HASH{create_thumbnail_page}) ||
      ($FILL_HASH{create_thumbnail_page} eq 'true')
      ){  # If this key doesn't exist it's probably the first time through this slide_show and the default is on.
      $FORM{thumbnail_chunk_visibility}     = "position:relative;visibility:visible;";
    }
    else{
      $FORM{thumbnail_chunk_visibility}     = "position:absolute;visibility:hidden;";
    }

    $FORM{autopilot_button_html}            = "^w_settings_tables.autopilot_button_html^";
    $FORM{autopilot_text_html}              = "^w_settings_tables.autopilot_text_html^";
    if(
      ($FILL_HASH{enable_autopilot}) &&
      ($FILL_HASH{enable_autopilot} eq 'true')
      ){
      $FORM{autopilot_chunk_visibility}     = "position:relative;visibility:visible;";
    }
    else{
      $FORM{autopilot_chunk_visibility}     = "position:absolute;visibility:hidden;";
    }

    ### Handle the mouseover toggle check
    #do not store the following in the conf, they are to be passed in the FORM hash for w_settings
    #and only apply to that step of manage, if they get stored in the slide_show conf they'll break 
    #the live slide show.
    $FORM{disable_mouseover_check_start}  = "^w_settings_tables.disable_mouseover_check_start^";
    $FORM{disable_mouseover_check_end}    = "^w_settings_tables.disable_mouseover_check_end^";
  }

  # End of FILL_HASH dependent code
  # ----------------------------------------------------------------------------------------------


  $partner->print($step,\%FORM,\%SHOWS);










##################################################################################################
### SUBROUTINES
### 




#----------------------------------------------------------------------------------------
sub tell_disk_usage{

  ### Determine space used, and stats (for upgrade pitch)
  my $user                = new O::User($ENV{HTTP_HOST});
  my $space_used          = int(compute_used("$user->{directory}/"));
  if($space_used<1024){
    $FORM{used_space}     = int($space_used) . " bytes";
    $FORM{disk_quota}     = int(($user->{quota} * 1024) * 1024) . " bytes (" . $user->{quota} . "MB)";
  }
  elsif($space_used<1048576){
    $FORM{used_space}     = int($space_used / 1024) . " kilobytes";
    $FORM{disk_quota}     = int($user->{quota} * 1024) . " kilobytes (" . $user->{quota} . "MB)";
  }
  else{
    $space_used           = int(($space_used / 1024) / 1024);
    $FORM{used_space}     = $space_used . " megabytes";
    $FORM{used_space}     = "1 megabyte"    if($space_used<1);
    $FORM{disk_quota}     = $user->{quota} . "MB";
  }

  return;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub determine_wizard{

  ################################################
  #
  # WIZARD OR NON-WIZARD?
  #  If there ISN'T a $FORM{next_page} then we check for the existence of the slide_show directory within the user's site
  #  ...If there ISN'T a directory then this is the first time, so we are in the WIZARD, otherwise this is a return trip so its NONWIZARD
  #
  #  !NOTE- The CONTENT should NOT specify WIZARD or NONWIZARD (the CGI checks for the slide_show directory)
  #
  ################################################

  my $user = O::User->new($ENV{HTTP_HOST});
  my $success = 0;

  if(! -d "$user->{directory}/slide_shows" ){
    $FORM{wizard}       = "true";
    $FORM{next_page}    = "w_intro";
    $FORM{prev_page}    = "w_intro";
  }
  else{
    #open conf in slide_shows and check for sitebuilder key
    my %CONF_HASH = conf_read( "$user->{directory}/slide_shows/slide_shows.conf" );
    $FORM{sitebuilder}  = $CONF_HASH{sitebuilder}   if exists $CONF_HASH{sitebuilder};
    $FORM{next_page}    = "manage_shows";
    $FORM{prev_page}    = "manage_shows";
  }

  return;
} 
#----------------------------------------------------------------------------------------




#----------------------------------------------------------------------------------------
sub validate_slide_show_name{ 

  my $user = O::User->new($ENV{HTTP_HOST});
  my $success = 0;
  my $error = "";
  my $conf_filename = "";

  #We want to store the name and path in the available slide shows conf file so we
  #first need to resolve the name into a path and verify that the path can be created
 
  $FORM{temp_slide_show_name} =~ s/[%^()@"'\\\/\.\?:;,|\{\}\+=~`<>\[\]\#\*\&\$]//g;
  $FORM{slide_show_path} = $FORM{temp_slide_show_name};
  $FORM{slide_show_path} =~ s/ /_/g;
  my $path_ok = 0;
  if( -d "$user->{directory}/slide_shows/$FORM{slide_show_path}" ){ #path already there?
    $FORM{error} = "^errortext.unable_to_store^ $FORM{slide_show_path}<BR>^errortext.already_exists^^errortext.unable_to_store2^";
  }
  else{ 
    #path not already there (probably user's first visit)
    if (&create_path){
      ### successfully created directory for slide_show, now try and save the name into the CONF file.
      $conf_filename = $user->{directory} . "/slide_shows/" . $FORM{slide_show_path} . "/" . $FORM{slide_show_path} . ".conf";
      if(!conf_write($conf_filename,{slide_show_name => $FORM{temp_slide_show_name}})){ 
        #since we just created a path based on a name, store the name in our CONF
        $FORM{error} = $O::conf_util::error;
      }
      else{ 
        $success = 1; 
      }
    }
    else{ 
      ### couldn't create the directory for the slide_show
      $FORM{error} = "^errortext.unable_to_store^ $FORM{slide_show_path}<BR>^errortext.unable_to_store2^";
    }
  }

  delete $FORM{temp_slide_show_name};  #remove this so we won't try and process it again later
  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub create_path{

  my $result = "";
  my $user = O::User->new($ENV{HTTP_HOST});

  require "File/Path.pm";
  $result = File::Path::mkpath("$user->{directory}/slide_shows/$FORM{slide_show_path}",0,0755);
  $result .= File::Path::mkpath("$user->{directory}/slide_shows/$FORM{slide_show_path}/thumbnails",0,0755);
  return $result;
}
#----------------------------------------------------------------------------------------






#----------------------------------------------------------------------------------------
sub build_image_drop_down{

  my $user = O::User->new($ENV{HTTP_HOST});
  my @objects = ();
  my @dirs = ();

  push @dirs, "$user->{directory}/";
  while(my $directory = shift(@dirs)){
    opendir(DIR,$directory);
    push @objects, $directory;
    while(my $fileName = readdir(DIR)){
      next if $fileName =~ /^\.|^filebox$/; # ok with s2dr2fb
      push @dirs, "$directory/$fileName";# if -d "$directory/$fileName";
      next unless -T "$directory/$fileName";
      push @objects, "$directory/$fileName";
    }
    closedir(DIR);
  }
  @objects = grep /\.(?:jpg|gif|jpeg|jpe|png)$/i, @objects;
  foreach my $item (@objects){
    $item =~ s/^$user->{directory}//;
    $item =~ s/\/+/\//g;
  }
  $FORM{sitewide_image_files} = "";
  $FORM{sitewide_image_files} = "<OPTION VALUE=''>^text.default_image_text^";
  $FORM{sitewide_image_files} .= "<OPTION VALUE='$_'>$_\n" foreach (@objects);
  if((@objects+0)==0){
    $FORM{sitewide_image_files} .= "<OPTION VALUE=''>^errortext.no_graphics_found^";
  }

  my $temp="";
  $temp = qq|<SCRIPT>var sitewide_image_files_javascript=new Array(|;
  $temp .= qq|"^text.default_image_text^",|;

  foreach my $item (@objects){
    $temp .= qq|"$item",|;
  }

  if((@objects+0)==0){
    $temp .= qq|"^errortext.no_graphics_found^",|;
  }

  $temp .= qq|"");</SCRIPT>|;
  $FORM{sitewide_image_files_javascript} = $temp;
  closedir (DIR);
}
#----------------------------------------------------------------------------------------




#----------------------------------------------------------------------------------------
sub save_image{

  my $user              = shift;
  my $error_message     = "";
  my %FILE              = ();

  $FILE{file}           = shift;
  $FILE{filename}       = shift;
  $FILE{content}        = shift;
  $FILE{overwrite}      = shift;
  $FILE{path_name}      = $FORM{slide_show_path};
  $FILE{max_file_size}  = $user->{file_size}*1024*1024;
  $FILE{actual_quota}   = $user->{quota}*1024*1024;
  $FILE{content_size}   = ((length $FILE{content}) -1);
  $FILE{space_used}     = compute_used($user->{directory});

  if(!$FILE{content}){
    $error_message      = "errortext.no_content";
  }

  if(
    (-e "$user->{directory}/slide_shows/$FILE{path_name}")  && 
    (!-d "$user->{directory}/slide_shows/$FILE{path_name}") &&
    (exists $FILE{overwrite})
    ){
    unlink "$user->{directory}/slide_shows/$FILE{path_name}";
  }

  if( $FILE{file} !~ /\.(?:jpg|gif|jpeg|jpe|png)$/i ){
    $error_message          = "errortext.bad_filetype";
    return $error_message;
  }

  if(
    (-e $FILE{file})  &&
    (!$FILE{overwrite})
    ){
    $error_message          = "errortext.file_exists";
    return $error_message;
  }

  if( $FILE{content_size} > $FILE{max_file_size} ){
    $error_message          = "errortext.too_large";
    return $error_message;
  }

  if( ($FILE{space_used} + $FILE{content_size}) > $FILE{actual_quota} ){
    $error_message          = "errortext.exceeds_quota";
    return $error_message;
  }

  if( !open(FH,">$FILE{file}") ){
    $error_message          = "errortext.cant_write_file";
    return $error_message;
  }

  print FH $FILE{content};
  close(FH);

  return "";
}
#----------------------------------------------------------------------------------------




#----------------------------------------------------------------------------------------
sub create_thumbnails{

  my $filename = '';
  my $success = 0;

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  my $user = O::User->new($ENV{HTTP_HOST});
  my $dir = $user->{directory}."/slide_shows/";
  my $conf_filename = $dir.$FORM{slide_show_path}."/".$FORM{slide_show_path}.".conf";

  ### If they want thumbnails, create them, if they don't check for old thumbnails and remove them.
  if (not exists $FORM{create_thumbnail_page}){
    $FORM{create_thumbnail_page} = "false";
    if(-d $user->{directory} . "/slide_shows/" . $FORM{slide_show_path} . "/thumbnails" ){
      if (!delete_show( $FORM{slide_show_path} . "/thumbnails" )){
        #no error currently, this just means we weren't able to clean up existing thumbnails.
        warn "couldn't clean up the existing thumbnails at $ENV{HTTP_HOST}";
      }
    }
  }
  else{

    ### Check for the necessary directories, if not there create them (they may have been deleted during editting).
    if(!-d $user->{directory} . "/slide_shows/" . $FORM{slide_show_path} . "/thumbnails" ){
      require "File/Path.pm";
      my $result = File::Path::mkpath("$user->{directory}/slide_shows/$FORM{slide_show_path}/thumbnails",0,0755);
    }

    ### determine number of pictures in show
    my %PIC_HASH = list_pictures($conf_filename);

    my $thumbnail_size = "100"; #default, in case somehow nothing is specified.
    if($FORM{thumbnail_size}){
      $thumbnail_size = $FORM{thumbnail_size};
    }
    elsif($PIC_HASH{thumbnail_size}){
      $thumbnail_size = $PIC_HASH{thumbnail_size};
    }

    for (my $index = 0; $index<$PIC_HASH{total_images}; $index++){
      my $image_filename = $PIC_HASH{image_url}[$index];

      next if ($image_filename !~ m@.(jpg|gif|jpeg|jpe|png)$@);

      my ($host) = $image_filename =~ m@(?:http://)?(.+?)/@;
      if(
        (!$host) || 
        ($host =~ m@^/@)
        ){
          $host = $ENV{HTTP_HOST};
      }

      #Make sure the GET will not contain http:// or the first occurence of $host (which we already extracted)
      $image_filename =~ s@^http://@@i;
      $image_filename =~ s@$host@@;

      my $url;
      if ($host eq $ENV{HTTP_HOST}){
        $url = "http://localhost:$ENV{SERVER_PORT}$image_filename";
      }
      else{
        $url = "http://$host$image_filename";
      }

      my ($thumbnail_filename,$thumbnail_extension) = $url =~ m@([^\/]+)\.(jpg|gif|jpeg|jpe|png)$@; #in case we want to impose a specific format and extension later

      my ($bin) = slap($url, "GET", "", make_headers({Host => $host}));
      if($bin){
        my $success = '';
        my $image = Image::Magick->new;
        $success = $image->BlobToImage( $bin );
        $success = '';

        my $orig_loop = ($image->Get('loop'));
        my @orig_dispose = ();
        my @orig_delay = ();
        my @orig_matte = ();
        if (scalar(@$image)>1){
          for (0..@$image-1){
           push @orig_matte,    ($image->[$_]->Get('matte'));     #scene transparency (true/false)
           push @orig_dispose,  ($image->[$_]->Get('dispose'));   #scene inter-image transition effect 0-none,1-none,2-bgcolor,3-last scene with 0,1
           push @orig_delay,    ($image->[$_]->Get('delay'));     #amount of time to wait on this scene before moving to next
          }
          $image->Set(adjoin=>1);   #store animated gifs as a single file, preserving a facsimile of the original animation in the thumbnail
        }

        $success = $image->Scale($thumbnail_size);
        $success = '';

        my $save_filename = "$user->{directory}/slide_shows/" . $FORM{slide_show_path} . "/thumbnails/th_" . $thumbnail_filename . "." . $thumbnail_extension;
        $success = $image->Write($save_filename); 
        $success = '';
      } #end if($bin)
    } #end for
  } #end else

  #store the thumbnail setting (for use with FILL HASH later)
  if(!conf_write($conf_filename,sort(\%FORM),{"error" => undef})){
    $FORM{error} = $O::conf_util::error;
  }

  return "";
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub delete_all_slide_shows{

  if (!delete_show("all")){
    $FORM{error_removeall} = "^errortext.unable_to_remove_dirs^";
    $FORM{next_page} = $FORM{current_page};
  } 
  else{
    $FORM{next_page} = "w_intro";
    $FORM{wizard} = "true";
  }
}
#----------------------------------------------------------------------------------------






#----------------------------------------------------------------------------------------
sub delete_one_slide_show{


  if(!$FORM{delete_show_name}){
    $FORM{error_removeone} = "^errortext.unable_to_remove_dir^";
    return;
  }

  if (!delete_show($FORM{delete_show_name})){
    $FORM{error_removeone} = "^errortext.unable_to_remove_dir^";
  } 

  $FORM{next_page} = "manage_shows";
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub upload_images{

  #
	# if there are graphics, find and store each, and put a new key into the global $FORM hash
	# write the file into the (user_site)/slide_show/(slide_show_path)/(filename)
  #  

  my $user            = new O::User($ENV{HTTP_HOST});
  my $error_message   = "";
  my $error           = "";
  my $index           = 0;
  my @inline_error    = ();

  my $overwrite       = "true"  if($FORM{overwrite});
  $FORM{overwrite}    = undef;

  foreach my $key (sort keys %FORM){
    if(($key =~ /_upload/) && ($FORM{$key}{content})){ 
      my ($filename)          = $FORM{$key}{filename} =~ m%([^\\\/]+)$%;
      my $file                = $user->{directory} . "/slide_shows/" . $FORM{slide_show_path} . "/$filename";
      $filename               = "/slide_shows/$FORM{slide_show_path}/" . $filename;

      my $temp_error_message = save_image($user, $file, $filename, $FORM{$key}{content}, $overwrite);
      if(length $temp_error_message > 0){
        $error = "^errortext.error_inline^";
        push @inline_error,"^error.inlineall;errortext=$temp_error_message;filename=" . $filename . ";^";
      }
      else{
        push @inline_error, "";  #zero fill array items in order to maintain correspondance between inline errors
      }

      $FORM{"picture".(++$index)."_mysitefile"} = $filename;
      delete $FORM{$key};
    }
  }

  for(0..$max_pics){
   push @inline_error, "";  #zero fill array items in order to maintain correspondance between inline errors
  }

  if(length $error > 0){
    $FORM{error} = $error;
    $FORM{inline_error} = \@inline_error;
  }
  return;
}
#----------------------------------------------------------------------------------------




#----------------------------------------------------------------------------------------
sub store_image_urls{

  my $user          = O::User->new($ENV{HTTP_HOST});
  my $success       = 0;
  my @inline_error  = ();
  my $error         = "";

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  ### Populate a CONF hash - This will be used for comparison to the FORM hash.
    # -If a CONF hash key matches an existing FORM hash key then the FORM hash key wins.
    # -If a CONF hash key doesn't exist then the FORM hash key wins.
    #   WHY do this? Because since the image data can be presented in pages of ten, the counting mechanism 
    #   needs a starting point or else it treats Image90 as Image1 (even if an Image1 existed previously).
    my %CONF_HASH = &read_raw_form_from_conf;

  ### Loop through each set of key values to convert form data into conf data
  my $index         = 1;
  my $total_images  = 0;
  for($index = 1; $index <= $max_pics; $index++){
    #isun $index .":". $total_images .":". $FORM{"picture".$index."_fromwhere"};

    my $overwrite="true"  if($FORM{"picture".$index."_overwrite_upload"});
    $FORM{"picture".$index."_overwrite_upload"} = undef;

    ### Now figure out which radio button was checked and pull the corresponding field containing a URL to the image
    if(!$FORM{"picture".$index."_fromwhere"}){
      if($CONF_HASH{"picture".$index."_url"}){
        $total_images++;
        push @inline_error,"";
        # populate this entry in the forms hash with the values from the conf hash (this is used later when building the linked list between slides)
        $FORM{"picture".$total_images."_fromwhere"}   = $CONF_HASH{"picture".$index."_fromwhere"};
        $FORM{"picture".$total_images."_next"}        = $CONF_HASH{"picture".$index."_next"};
        $FORM{"picture".$total_images."_previous"}    = $CONF_HASH{"picture".$index."_previous"};
        $FORM{"picture".$total_images."_url"}         = $CONF_HASH{"picture".$index."_url"};
        $FORM{"picture".$total_images."_mysitefile"}  = $CONF_HASH{"picture".$index."_mysitefile"};
        $FORM{"picture".$total_images."_fileurl"}     = $CONF_HASH{"picture".$index."_fileurl"};
        $FORM{"picture".$total_images."_upload"}      = undef;
	      $FORM{"picture".$total_images."_caption"}     = $CONF_HASH{"picture".$index."_caption"};
	      $FORM{"picture".$total_images."_width"}       = $CONF_HASH{"picture".$index."_width"};
	      $FORM{"picture".$total_images."_height"}      = $CONF_HASH{"picture".$index."_height"};
	      $FORM{"picture".$total_images."_mprops"}      = $CONF_HASH{"picture".$index."_mprops"};
	      $FORM{"picture".$total_images."_preview_src"} = $CONF_HASH{"picture".$index."_preview_src"};
        $FORM{"picture".$total_images.".jpg"}         = $CONF_HASH{"picture".$index.".jpg"};
        next;
      }
    }
    else{  
    #if($FORM{"picture".$index."_fromwhere"}){
      if($FORM{"picture".$index."_fromwhere"} eq 'none'){
        # "No Image" is selected (delete all values associated with that entry, and each subsequent entry needs to be shuffled up by one.)
        # Reset any keys that may have existed (this could be editting an existing slide_show)
        $FORM{"picture".$index."_fromwhere"}          = undef;
        $FORM{"picture".$index."_next"}               = undef;
        $FORM{"picture".$index."_previous"}           = undef;
        $FORM{"picture".$index."_url"}                = undef;
        $FORM{"picture".$index."_mysitefile"}         = undef;
        $FORM{"picture".$index."_fileurl"}            = undef;
        $FORM{"picture".$index."_upload"}             = undef;
	      $FORM{"picture".$index."_caption"}            = undef;
	      $FORM{"picture".$index."_width"}              = undef;
	      $FORM{"picture".$index."_height"}             = undef;
	      $FORM{"picture".$index."_mprops"}             = undef;
	      $FORM{"picture".$index."_preview_src"}        = undef;
        $FORM{"picture".$index.".jpg"}                = undef;
        next;
      }

      elsif($FORM{"picture".$index."_fromwhere"} eq 'my_computer'){
        $total_images++;
        #store the image from the _upload control
          my ($filename) = $FORM{"picture".$index."_upload"}{filename} =~ m%([^\\\/]+)$%;
          if(!length $filename){
            $error = "^errortext.error_inline^";
            push @inline_error,"^error.inlineall;errortext=errortext.no_file_specified^";
          }
          else{
            my $file = $user->{directory} . "/slide_shows/" . $FORM{slide_show_path} . "/$filename";
            $filename = "/slide_shows/$FORM{slide_show_path}/" . $filename;

            my $temp_error_message = save_image($user, $file, $filename, $FORM{"picture".$index."_upload"}{content}, $overwrite);

            if(length $temp_error_message > 0){

            ### problem 07/19/01: when w_images is re-served with the file already exists error showing, the radio button is still 
            #     set on "upload file" and the <input type=file> is now blank.... if the form is resubmitted without 
            #     populating that file field with a filename then another error occurs "No file specified"... this happens 
            #     to me regularly.  So, if the file already exists, try setting the radio option to "from my web site" 
            #     and setting the drop down value to the filename that exists on the web site. (Then if the user really 
            #     meant to overwrite the file they can do so, but if they didn't there is graceful error fallback.
              $FORM{"picture".$index."_fromwhere"}    = "mysite";
              $FORM{"picture".$index."_preview_src"}  = $filename;
              $FORM{"picture".$index."_mysitefile"}   = $filename;
            #
            ###

              $error = "^errortext.error_inline^";
              push @inline_error,"^error.inlineall;errortext=$temp_error_message;filename=" . $filename . ";error_size=1;nobold=1;^";
            }
            else{
              $FORM{"picture".$index."_fromwhere"} = 'mysite';
              $FORM{"picture".$index."_url"} = $filename;
              $FORM{"picture".$index."_mysitefile"} = $filename;
              $FORM{"picture".$index."_preview_src"} = $filename;
              push @inline_error, "";  #zero fill array items in order to maintain correspondance between inline errors
            }
          }
      }

      elsif($FORM{"picture".$index."_fromwhere"} eq 'mysite'){
        $total_images++;
        if($FORM{"picture".$index."_mysitefile"}){
          $FORM{"picture".$index."_mysitefile"} =~ s/'"|//g;
          $FORM{"picture".$index."_url"} = $FORM{"picture".$index."_mysitefile"};
          push @inline_error, "";  #zero fill array items in order to maintain correspondance between inline errors
        }
        else{
          $error = "^errortext.error_inline^";
          push @inline_error,"^error.inlineall;errortext=errortext.no_file_specified^";
        }
      }

      elsif($FORM{"picture".$index."_fromwhere"} eq 'the_web'){
        $total_images++;
        if($FORM{"picture".$index."_fileurl"}){
          $FORM{"picture".$index."_fileurl"} =~ s/'"|//g;
          $FORM{"picture".$index."_url"} = $FORM{"picture".$index."_fileurl"};
          push @inline_error, "";  #zero fill array items in order to maintain correspondance between inline errors
        }
        else{
          $error = "^errortext.error_inline^";
          push @inline_error,"^error.inlineall;errortext=errortext.no_file_specified^";
        }
      }

      if($FORM{"picture".$index."_caption"}){
        $FORM{"picture".$total_images."_caption"}     = $FORM{"picture".$index."_caption"};
      }else{
        $FORM{"picture".$total_images."_caption"}     = undef;
      }

      if($FORM{"picture".$index."_width"}){
        $FORM{"picture".$total_images."_width"}       = $FORM{"picture".$index."_width"};
      }else{
        $FORM{"picture".$total_images."_width"}       = undef;
      }

      if($FORM{"picture".$index."_height"}){
        $FORM{"picture".$total_images."_height"}      = $FORM{"picture".$index."_height"};
      }else{
        $FORM{"picture".$total_images."_height"}      = undef;
      }

      if($FORM{"picture".$index."_mprops"}){
        $FORM{"picture".$total_images."_mprops"}      = $FORM{"picture".$index."_mprops"};
      }else{
        $FORM{"picture".$total_images."_mprops"}      = "false";
      }

      if($FORM{"picture".$index."_fromwhere"}){
        $FORM{"picture".$total_images."_fromwhere"}   = $FORM{"picture".$index."_fromwhere"};
      }else{
        $FORM{"picture".$total_images."_fromwhere"}   = undef;
      }

      if($FORM{"picture".$index."_mysitefile"}){
        $FORM{"picture".$total_images."_mysitefile"}  = $FORM{"picture".$index."_mysitefile"};
      }else{
        $FORM{"picture".$total_images."_mysitefile"}  = undef;
      }

      if($FORM{"picture".$index."_fileurl"}){
        $FORM{"picture".$total_images."_fileurl"}     = $FORM{"picture".$index."_fileurl"};
      }else{
        $FORM{"picture".$total_images."_fileurl"}     = undef;
      }

      if($FORM{"picture".$index."_preview_src"}){
        $FORM{"picture".$total_images."_preview_src"} = $FORM{"picture".$index."_preview_src"};
      }else{
        $FORM{"picture".$total_images."_preview_src"} = undef;
      }

      $FORM{"picture".$total_images."_url"}           = $FORM{"picture".$index."_url"};
      $FORM{"picture".$total_images.".jpg"}           = "picture".$total_images;
      $FORM{"picture".$total_images."_next"}          = undef;
      $FORM{"picture".$total_images."_previous"}      = undef;
      $FORM{"picture".$total_images."_upload"}        = undef;

      if($total_images != $index){
        $FORM{"picture".$index."_upload"}             = undef;
        $FORM{"picture".$index."_mysitefile"}         = undef;
        $FORM{"picture".$index."_fileurl"}            = undef;
        $FORM{"picture".$index."_caption"}            = undef;
        $FORM{"picture".$index."_width"}              = undef;
        $FORM{"picture".$index."_height"}             = undef;
        $FORM{"picture".$index."_fromwhere"}          = undef;
        $FORM{"picture".$index."_mprops"}             = undef;
        $FORM{"picture".$index."_preview_src"}        = undef;
        $FORM{"picture".$index."_url"}                = undef;
        $FORM{"picture".$index."_next"}               = undef;
        $FORM{"picture".$index."_previous"}           = undef;
      }
    }
  } #end for loop

  for(($total_images+1)..$max_pics){
    $FORM{"picture".$_.".jpg"}                        = undef;
    $FORM{"picture".$_."_upload"}                     = undef;
    $FORM{"picture".$_."_mysitefile"}                 = undef;
    $FORM{"picture".$_."_fileurl"}                    = undef;
    $FORM{"picture".$_."_caption"}                    = undef;
    $FORM{"picture".$_."_width"}                      = undef;
    $FORM{"picture".$_."_height"}                     = undef;
    $FORM{"picture".$_."_fromwhere"}                  = undef;
    $FORM{"picture".$_."_mprops"}                     = undef;
    $FORM{"picture".$_."_preview_src"}                = undef;
    $FORM{"picture".$_."_url"}                        = undef;
    $FORM{"picture".$_."_next"}                       = undef;
    $FORM{"picture".$_."_previous"}                   = undef;
    push @inline_error, "";  #zero fill array items in order to maintain correspondance between inline errors
  }

  $FORM{total_images} = $total_images;


  ###
  ### Now link together a sequence forward and backward through the picture collection
  ###


  ### Find the last "pictureX_url" on the list (since a HASH isn't guaranteed to be ordered, we will calculate the highest $index that occurs and assume it's the last image)
  my $highest_number  = 0;
  for(my $index=1; $index<=$max_pics; $index++){
    if($FORM{"picture".$index."_url"}){ 
      if(
        (!$highest_number) || 
        ($highest_number<$index)
        ){ 
          $highest_number = $index;
        }
    }
  }


  ### Now, scan forward through the list linking existing pictureX_url with lower numbers to ones with higher, and vice versa
  my $prev_url            = "";
  my $needs_next_url      = "";
  my $first_confirmed_url = "";
  my $last_confirmed_url  = "";
  for(my $index = 1; $index<=$total_images; $index++){
    if($FORM{"picture".$index."_url"}){
      if(!$first_confirmed_url){ $first_confirmed_url = $index; }
      $last_confirmed_url = $index;

      if(!$prev_url){
        $FORM{"picture".$index."_previous"}       = "picture".$highest_number.".jpg";
      }
      else{
        $FORM{"picture".$index."_previous"}       = "picture".$prev_url.".jpg";
      }
      $prev_url = $index;

      if($needs_next_url){
        $FORM{"picture".$needs_next_url."_next"}  = "picture".$index.".jpg";
      }
      $needs_next_url = $index;        
    }
  }
  $FORM{"picture".$last_confirmed_url."_next"}    = "picture".$first_confirmed_url.".jpg";


  ### Now create a thumbnail entry (even if they aren't using thumbnails.... on/off is acheived by showing, or not showing a link.)
  $FORM{"thumbnail.jpg"}        = "thumbnail";
  $FORM{"thumbnail_caption"}    = "^w_settings_tables.thumbnail_caption^";
  $FORM{"thumbnail_next"}       = "picture".$first_confirmed_url.".jpg";
  $FORM{"thumbnail_previous"}   = "picture".$highest_number.".jpg";


  ###
  ### END: Now link together a sequence forward and backward through the picture collection
  ###


  my $conf_filename = $user->{directory}."/slide_shows/".$FORM{slide_show_path}."/".$FORM{slide_show_path}.".conf";
  if(!conf_write($conf_filename,sort(\%FORM))){
    $FORM{error} = $O::conf_util::error;
  }
  else{
    $success = 1; 
  }


  ### If we are editting an existing slide show, we want to create thumbnails if this show supports them (since the w_settings page
    # where thumbnails are specified is NOT going to be visited in this context.)
  ### Note: as written, this must happen AFTER we update the conf with the new values since the thumbnail list is produced by reading the conf
  if($CONF_HASH{create_thumbnails} && ($CONF_HASH{create_thumbnails} eq 'true')){
    $FORM{create_thumbnail_page} = "true";
    &create_thumbnails;
  }

  if(length $error > 0){
    $FORM{error} = $error;
    $FORM{inline_error} = \@inline_error;
  }

  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub store_settings_data{

  my $success = 0;

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  my $user = O::User->new($ENV{HTTP_HOST});
  my $dir = $user->{directory}."/slide_shows/";
  my $conf_filename = $dir.$FORM{slide_show_path}."/".$FORM{slide_show_path}.".conf";
  

  ### Handle sitebuilder_start_with 
  if($FORM{sitebuilder_start_with}){
    &starts_with_value("write");
  }
  else{
    my $sitebuilder_settings = &read_sitebuilder_value;
    if($sitebuilder_settings->{default_slide_show} eq $FORM{slide_show_path}){
      $FORM{sitebuilder_start_with}   = undef;
      &starts_with_value("write");
    }
  }
  $FORM{sitebuilder_start_with}       = undef;    #don't store this in individual slide_show confs, it belongs in the main conf since its global to slide show

  ### If no "hide_other_shows" key/value passed force it to undef to clear it from the conf, this setting shows or doesn't show the links to "Other Shows:"
  if(!$FORM{hide_other_shows}){
    $FORM{hide_other_shows}           = undef;
  }

  ### Handle the font characteristics 
  $FORM{title_fontfamily}             = "font-family:" . URLDecode($FORM{font_1}) . URLDecode($FORM{font_2}) . URLDecode($FORM{font_3});
  $FORM{caption_fontfamily}           = "font-family:" . URLDecode($FORM{font_1}) . URLDecode($FORM{font_2}) . URLDecode($FORM{font_3});

  if(exists $FORM{font_size_unit} && ($FORM{font_size_unit} ne '')){
    $FORM{title_fontsize}             = "font-size:" . URLDecode($FORM{font_size} . $FORM{font_size_unit});
    $FORM{caption_fontsize}           = "font-size:" . URLDecode($FORM{font_size} . $FORM{font_size_unit});
    $FORM{old_html_size}              = undef;
  }
  else{
    $FORM{old_html_size}              = " SIZE=" . URLDecode($FORM{font_size});
  }

  if($FORM{mbold}){
		if($FORM{mbold} eq 'true'){
	    $FORM{title_fontweight}         = "font-weight:bold;";
	    $FORM{caption_fontweight}       = "font-weight:bold;";
		}
		else{
	    $FORM{title_fontweight}         = "font-weight:normal;";
	    $FORM{caption_fontweight}       = "font-weight:normal;";
		}
  }

  if($FORM{mitalic}){
		if($FORM{mitalic} eq 'true'){
	    $FORM{title_fontstyle}          = "font-style:italic;";
	    $FORM{caption_fontstyle}        = "font-style:italic;";
		}
		else{
	    $FORM{title_fontstyle}          = "font-style:normal;";
	    $FORM{caption_fontstyle}        = "font-style:normal;";
		}
  }

  if($FORM{munderline}){
		if($FORM{munderline} eq 'true'){
	    $FORM{title_textdecoration}     = "text-decoration:underline;";
	    $FORM{caption_textdecoration}   = "text-decoration:underline;";
	  }
		else{
	    $FORM{title_textdecoration}     = "text-decoration:none;";
	    $FORM{caption_textdecoration}   = "text-decoration:none;";
		}
	}

  if($FORM{mcolor}){
    $FORM{title_color}                = "color:" . $FORM{mcolor} . ";";
    $FORM{caption_color}              = "color:" . $FORM{mcolor} . ";";
  }

  ### Handle TABLE characteristics
  # Note: as of this writing these issues are not handled through the interface, so since they make the best sense I am setting them as defaults
  # until Jason has a chance to address whether the interface needs to be revisited to offer greatly flexibility here.
  $FORM{tablealign}                   = "ALIGN=CENTER";
  $FORM{cellalign}                    = "ALIGN=CENTER";

  ### Handle which button interface to use (or text) for the navbar
  if($FORM{navigation_style} eq '1'){
    $FORM{navbar_html}                = "^w_settings_tables.text_navbar^";
  }
  else{
    $FORM{navbar_html}                = "^w_settings_tables.graphical_navbar^";
  }

  $FORM{disable_mouseovers}           = "false" if(not exists $FORM{disable_mouseovers});

  ### Handle Featured Image data
  if($FORM{create_featured_image}){
    #$FORM{featured_image_title}      =~ s/[%^()@"'\\\/\.\?:;,|\{\}\+=~`<>\[\]\#\*\&\$]//g;
    $FORM{featured_image_title}       = URLDecode($FORM{featured_image_title});
    $FORM{scheduled_image_change}     = ((time)+$FORM{featured_image_frequency});
    $FORM{current_featured_image}     = 1;
    if(
      ($FORM{border_color}) && 
      (length $FORM{border_color} > 1)
      ){
      $FORM{featured_border_color}    = "border-color:" . $FORM{border_color} . ";";
    }
    else{
      $FORM{featured_border_color}    = undef;
    }
    &get_featured_image_url; #need this in order to show the featured image picture during the success page phase
  }
  else{
    $FORM{create_featured_image} = "false";
  }

  ### Handle Auto Pilot data
  $FORM{enable_enable}                = undef   if(not exists $FORM{enable_autopilot});
  $FORM{autopilot_running}            = undef   if(not exists $FORM{autopilot_running});
  $FORM{autopilot_interval}           = undef   if(not exists $FORM{autopilot_interval});

  ### Now store to the CONF
  if(!conf_write($conf_filename,sort(\%FORM))){
    $FORM{error} = $O::conf_util::error;
  }
  else{ 
    $success = 1; 
  }
  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub get_slide_show_url{

  my $success = 0;

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  my $user = O::User->new($ENV{HTTP_HOST});
  my $conf_filename = $user->{directory}."/slide_shows/" . $FORM{slide_show_path} . "/" . $FORM{slide_show_path} . ".conf";
  
  my %CONF_HASH = conf_read( $conf_filename );

  $FORM{slide_show_name} = $CONF_HASH{slide_show_name};
	$FORM{slide_show_url} = "http://" . $user->{site} . "/slide_show.html?show=" . $FORM{slide_show_path} . "&picture=picture1.jpg";

  $success = 1;
  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub get_featured_image_url{

  my $success = 0;

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  my $user = O::User->new($ENV{HTTP_HOST});
  my $dir = $user->{directory} . "/slide_shows/";
  my $conf_filename = $dir . $FORM{slide_show_path} . "/" . $FORM{slide_show_path} . ".conf";
  
  my %CONF_HASH = conf_read($conf_filename);
  $FORM{featured_image} = $CONF_HASH{picture1_url};
	$FORM{featured_image_url} = "http://" . $user->{site} . "/" . $FORM{slide_show_path} . "/featured.jpg";
  $success = 1;
  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub store_sitebuilder_value{

  my $user = O::User->new($ENV{HTTP_HOST});
  my $success = 0;
  my $error = "";

  # a /slide_shows directory MUST already exist at the site BEFORE this subroutine is called
  if(!conf_write("$user->{directory}/slide_shows/slide_shows.conf",{sitebuilder => $FORM{store_sitebuilder_value}})){
    $FORM{error} = $O::conf_util::error;
  }
  else{ 
    $success = 1; 
  }
  $FORM{sitebuilder} = $FORM{store_sitebuilder_value};
  delete $FORM{store_sitebuilder_value};  #remove this so we won't try and process it again later
  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub read_sitebuilder_value{

  my $user        = O::User->new($ENV{HTTP_HOST});
  my %CONF_HASH   = conf_read("$user->{directory}/slide_shows/slide_shows.conf");

#  if (!scalar keys %CONF_HASH){ 
#    $FORM{error} =  $O::conf_util::error;
#    $FORM{errorlink} =  "^errortext.slide_show_usage_link^";
#    $step='/slide_show_manage/error_only.htm';
#    my $HTML = $partner->load_content($step);
#    wrap(text=>\$HTML,partner=>$partner,step=>$step,form=>[\%FORM]);
#    $partner->{content} = $HTML;
#    return $partner->{content};
#  }

  return \%CONF_HASH;
}
#----------------------------------------------------------------------------------------




#----------------------------------------------------------------------------------------
sub check_site_for_slide_show_html{

  my $user = O::User->new($ENV{HTTP_HOST});
  my $success = 0;
  my $error = "";

	#If the target site doesn't already have a file named slide_show.html in the site root folder, copy our generic one there.
  if(! -e "$user->{directory}/slide_show.html" ){
	  my $filename = $partner->get_content_filename('slide_show.html');
    if(! -e $filename){ isun "couldn't find the source file to copy in the specified path" };
    my $success = copy("$filename","$user->{directory}/slide_show.html");
 		if(!$success){
	    $FORM{error} = "$!^errortext.no_slide_show_html^";
			$success=0;
		}
  }

  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub starts_with_value{

  my $op        = shift || "read";
  my $user      = O::User->new($ENV{HTTP_HOST});
  my $success   = 0;
  my $error     = "";

  # a /slide_shows directory MUST already exist at the site BEFORE this subroutine is called
  #my $default_slide_show = "/" . $FORM{slide_show_path} . "/picture1.jpg";
  #if(!conf_write("$user->{directory}/slide_shows/slide_shows.conf",{default_slide_show => $FORM{slide_show_path}})){
  #  $FORM{error} = $O::conf_util::error;
  #}
  if($op eq 'write'){
    if(!conf_write("$user->{directory}/slide_shows/slide_shows.conf",{default_slide_show => $FORM{sitebuilder_start_with}})){
      $FORM{error} = $O::conf_util::error;
    }
    else{ 
      $success = 1; 
    }
    delete $FORM{sitebuilder_starts_with};  #remove this so we won't try and process it again later
    return $success;
  }
  elsif($op eq 'read'){
    my %CONF_HASH   = conf_read("$user->{directory}/slide_shows/slide_shows.conf");
    if (!$CONF_HASH{default_slide_show}){
      return "None Specified";
    }
    else{
      return $CONF_HASH{default_slide_show};
    }
  }
  return $success;
}
#----------------------------------------------------------------------------------------




#----------------------------------------------------------------------------------------
sub read_raw_form_from_conf{

  my $success = 0;

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  my $user = O::User->new($ENV{HTTP_HOST});
  my $dir = $user->{directory}."/slide_shows/";
  my $conf_filename = $dir.$FORM{slide_show_path}."/".$FORM{slide_show_path}.".conf";
  
  my %CONF_HASH = conf_read( $conf_filename );

  # URL Decode the fields that FILL will need
  $CONF_HASH{font_1}          = URLDecode($CONF_HASH{font_1})         if(exists $CONF_HASH{font_1});
  $CONF_HASH{font_2}          = URLDecode($CONF_HASH{font_2})         if(exists $CONF_HASH{font_2});
  $CONF_HASH{font_3}          = URLDecode($CONF_HASH{font_3})         if(exists $CONF_HASH{font_3});
  $CONF_HASH{font_family}     = URLDecode($CONF_HASH{font_family})    if(exists $CONF_HASH{font_family});
  $CONF_HASH{font_size_unit}  = URLDecode($CONF_HASH{font_size_unit}) if(exists $CONF_HASH{font_size_unit});
  # END URL Decode the fields that FILL will need

  my @preview_src = ();
  for (my $index = 1; $index <= $max_pics; $index++){
    if(exists $CONF_HASH{"picture".$index."_url"}){
      push @preview_src, $CONF_HASH{"picture".$index."_url"}
    }
    else{
      push @preview_src, "^slide_show_manage.default_preview_image^";      
    }
  } $FORM{preview_src} = \@preview_src;

  return %CONF_HASH;
}
#----------------------------------------------------------------------------------------








#----------------------------------------------------------------------------------------
sub prep_image_order{

  #need to produce an ordered list of images from the conf, in <OPTION> format

  my $success = 0;

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  my $user = O::User->new($ENV{HTTP_HOST});
  my $dir = $user->{directory}."/slide_shows/";
  my $conf_filename = $dir.$FORM{slide_show_path}."/".$FORM{slide_show_path}.".conf";

  my %IMAGES_HASH = list_pictures($conf_filename); #Note- these need to be returned in order

  $IMAGES_HASH{images_option_list} = '';
  foreach my $index ( 0 .. $#{ $IMAGES_HASH{image_url} }){
    $IMAGES_HASH{images_option_list} .= "<OPTION VALUE='" . $IMAGES_HASH{image_url}[$index] . "'>" . $IMAGES_HASH{image_url}[$index] . "</OPTION>\n";
  }
  
  return %IMAGES_HASH;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub store_edit_table_values{

  my $user          = O::User->new($ENV{HTTP_HOST});
  my $success       = 0;
  my @inline_error  = ();
  my $error         = "";

  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  if($FORM{table_align}){
    $FORM{featured_table_align}         = " ALIGN=" . $FORM{table_align}; 
  }
  else{
    $FORM{table_align}                  = undef;
    $FORM{featured_table_align}         = undef;
  }

  if($FORM{table_valign}){
    $FORM{featured_table_valign}        = " VALIGN=" . $FORM{table_valign};
  }
  else{
    $FORM{table_valign}                 = undef;
    $FORM{featured_table_valign}        = undef;
  }

  if($FORM{table_width}){
    my $temp_unit                       = "";
    $temp_unit                          = "%" if($FORM{table_width_unit} && ($FORM{table_width_unit} eq 'percent'));
    $FORM{featured_table_width}         = " WIDTH=" . $FORM{table_width} . $temp_unit;
  }
  else{
    $FORM{table_width}                  = undef;
    $FORM{featured_table_width}         = undef;
  }

  if($FORM{table_height}){
    my $temp_unit                       = "";
    $temp_unit                          = "%" if($FORM{table_height_unit} && ($FORM{table_height_unit} eq 'percent'));
    $FORM{featured_table_height}        = " HEIGHT=" . $FORM{table_height} . $temp_unit;
  }
  else{
    $FORM{table_height}                 = undef;
    $FORM{featured_table_height}        = undef;
  }

  if($FORM{table_color}){
    $FORM{featured_table_color}         = " BGCOLOR='" . $FORM{table_color} . "'";
  }
  else{
    $FORM{table_color}                  = undef;
    $FORM{featured_table_color}         = undef;
  }

  if($FORM{table_cellspacing}){
    $FORM{featured_table_cellspacing}   = " CELLSPACING=" . $FORM{table_cellspacing};
  }
  else{
    $FORM{table_cellspacing}            = undef;
    $FORM{featured_table_cellspacing}   = undef;
  }

  if($FORM{table_cellpadding}){
    $FORM{featured_table_cellpadding}   = " CELLPADDING=" . $FORM{table_cellpadding};
  }
  else{
    $FORM{table_cellpadding}            = undef;
    $FORM{featured_table_cellpadding}   = undef;
  }

  if(
    ($FORM{border_color}) && 
    (length $FORM{border_color} > 1)
    ){
    $FORM{featured_border_color}      = "border-color:" . $FORM{border_color} . ";";
  }
  else{
    $FORM{border_color}                 = undef;
    $FORM{featured_border_color}        = undef;
  }

  if($FORM{fmcolor}){
    $FORM{featured_title_color}         = "color:" . $FORM{fmcolor} . ";";
    $FORM{featured_caption_color}       = "color:" . $FORM{fmcolor} . ";";
  }
  else{
    $FORM{fmcolor}                      = undef;
    $FORM{featured_title_color}         = undef;
    $FORM{featured_caption_color}       = undef;
  }

  if($FORM{border_width}){
    $FORM{featured_border_width}        = "border-width:" . $FORM{border_width} . "px;";
  }
  else{
    $FORM{border_width}                 = undef;
    $FORM{featured_border_width}        = undef;
  }

  my $conf_filename = $user->{directory}."/slide_shows/".$FORM{slide_show_path}."/".$FORM{slide_show_path}.".conf";
  if(!conf_write($conf_filename,sort(\%FORM))){
    $FORM{error} = $O::conf_util::error;
  }
  else{
    $success = 1; 
  }

  if(length $error > 0){
    $FORM{error} = $error;
    $FORM{inline_error} = \@inline_error;
  }
	
  return $success;
}
#----------------------------------------------------------------------------------------





#----------------------------------------------------------------------------------------
sub sort_images_in_conf{

  #resolve "new_list_order" into individual _url values (split based on comma)
  #build a list of applicable key/values from the conf
  #examine the list for a match of each value and move all related keys form TEMP1 has to TEMP2 hash (using the index this should reorder the list)
  
  #loop through each and scan for a matching _url value...
  #when found, move all data related to that key, to it's new ordered location

  my $success = 0;
  my %CONF_HASH = &read_raw_form_from_conf;
  my @slide_items = split /,/, $FORM{store_list_order};
  my $old = '';
  my %TEMP_HASH = (); #this is the existing order (different from CONF_HASH in that it only contain relevant hash keys... probably unnecessarily redundant)
  my %NEW_HASH = (); #this will hold the new order

      
  #get only the applicable keys
  foreach my $key (keys(%CONF_HASH)){
    if($key =~ /^(picture).+(_)/){
      $TEMP_HASH{$key} = $CONF_HASH{$key};
    }
  }
  
  for (my $index = 0; $index<scalar(@slide_items); $index++){
    #find a matching _url value (problem: what if more than one _url value is the same, how do we discern slides at that point?)
    #for now, too bad... since there isn't any way for the user to discern which slide is which either if they are the same url
    foreach my $key (keys(%TEMP_HASH)){
      if($key =~ /^(picture).+(_url)$/){
        if($slide_items[$index] eq $CONF_HASH{$key}){
          ($old) = $key =~ /^picture(.+)_url/;
          foreach my $key (keys(%TEMP_HASH)){
            if($key =~ /(picture($old)_)/){
              my ($ext) = $key =~ /^picture.+(_.+)$/;
              
              #if the extension is "_previous" or "_next" we need to recalculate that based on the new positions
              if($ext eq '_previous'){
                if($index > 0){
                  $NEW_HASH{"picture".($index+1).$ext} = "picture".($index).".jpg";
                }
                else{
                  $NEW_HASH{"picture".($index+1).$ext} = "picture".(scalar(@slide_items)).".jpg";
                }
              }

              elsif($ext eq '_next'){
                if($index < (scalar(@slide_items)-1)){
                  $NEW_HASH{"picture".($index+1).$ext} = "picture".($index+2).".jpg";
                }
                else{
                  $NEW_HASH{"picture".($index+1).$ext} = "picture1.jpg";
                }
              }
              #else, if not "_previous" or "_next" then just copy it across to the new location
              else{
                $NEW_HASH{"picture".($index+1).$ext} = $TEMP_HASH{$key};
              }
            }
          }
        }
      }
    }
  }
  

  #now store the new data back out to the conf
  ### $FORM{slide_show_path} must already exist (we derive a conf filename by combining it with $user)
  if(!$FORM{slide_show_path}){
    $FORM{error} = "^errortext.no_conf_filename^";
    return $success;
  }

  my $user = O::User->new($ENV{HTTP_HOST});
  my $dir = $user->{directory}."/slide_shows/";
  my $conf_filename = $dir.$FORM{slide_show_path}."/".$FORM{slide_show_path}.".conf";
  
  if(!conf_write($conf_filename,sort(\%NEW_HASH))){
    $FORM{error} = $O::conf_util::error;
  }
  else{ 
    $success = 1; 
  }
  return $success;
}
#----------------------------------------------------------------------------------------