
  // class.bgallery.js
  // Copyright (c) 2005,2006 Kevin Kaiser / Data Resolutions

  try {

    if (typeof(Basis) == 'undefined') {

      throw "";

    } // end if

  } catch (e) {

    throw "Basis.bgallery depends on Basis!";

  } // end try

  if (typeof(Basis.bgallery) == 'undefined') {

    Basis.bgallery = {};

  } // end if

  Basis.bgallery.NAME    = 'Basis.bgallery';
  Basis.bgallery.VERSION = '0.1';

  Basis.bgallery.__repr__ = function () {

    return '[' + this.NAME + ' ' + this.VERSION + ']';

  }; // end __repr__()

  Basis.bgallery.toString = function () {

    return this.__repr__();

  }; // end toString()

  Basis.bgallery.gallery = function () {

    this.__init__();

  }; // end Basis.bgallery.gallery()

  Basis.bgallery.gallery.prototype = {

    __init__: function () {

      this.files = []; // this.files[RANK] = array( "id",
                       //                           "filename",
                       //                           "url",
                       //                           "comment",
                       //                           "size" => array("w","h")
                       //                         );
      this.list;

      this.parent_element;
      this.output;

      this.logged_in = false;

      this.create_slideshow();

      document.twg_upload_completed = function () {
  
        var obj = MochiKit.DOM.getElement("uploader_container");

        if (obj) {

          MochiKit.DOM.removeElement(obj);

        } // end if

        Basis.misc_vars.build_gallery_popup = Basis.popup({"id"           : "build_gallery_popup",
                                                           "window_title" : "Resizing Images",
                                                           "html"         : '<div>Please wait while we process and resize any newly uploaded images.</div>\
                                                                             <div style="text-align: center; padding: 10px;"><img src="images/images/ajax_loading.gif"></div>'
                                                          });

        var as   = new Basis.ajax_scaffold;
        as.alias = "twg_upload_completed";
        as.sid   = "null";
        as.url   = (window.location+"");

        if (as.url.indexOf("?") == -1) {

          as.url = as.url+"?ajax_load=true";

        } else {

          as.url = as.url+"&ajax_load=true";

        } // end if

        as.pvar  = this;

        as.on_success = function (req) {

          var response = req.responseText;

          if (response == "true") {

            var obj = MochiKit.DOM.getElement("build_gallery_popup");
    
            if (obj) {
    
              MochiKit.DOM.removeElement(obj);
    
            } // end if

            Basis.misc_vars.build_gallery_popup = Basis.popup({"id"           : "build_gallery_popup",
                                                               "window_title" : "Resizing Images",
                                                               "html"         : "<div>Resizing completed! Reloading page in 3 seconds...</div>"
                                                              });

            MochiKit.Async.callLater("3",function () {

              window.location = (window.location+"");

            });

          } // end if

        };

        as.post();

      }; // end twg_upload_completed()

      Basis.misc_vars.dashboard  = Basis.misc_vars.dashboard ? Basis.misc_vars.dashboard : {};
      Basis.misc_vars.dashboard.toggle_uploader = MochiKit.Base.bind(function () {

        this.toggle_uploader();

      }, this);

    }, // end __init__()

    add_image: function (rank,options) {

      if (rank && options && options["id"] && options["filename"] && options["url"]) {

        this.files = Basis.array_insert(this.files, rank, options);

      } // end if

    }, // end add_image()

    archive_selected_images: function() {

      var folder_name = prompt("Name of Archive:");

      if (folder_name) {

        var to_archive = new Array();
  
        for (var i in this.files) {
  
          if (this.is_file(this.files[i])) {
  
            if (this.files[i].checked == true) {
  
              to_archive[to_archive.length] = this.files[i]["id"];
  
            } // end if
  
          } // end if
  
        } // end for
  
        if (to_archive.length>0) {

          var to_post             = new Object();

          to_post["folder_name"]  = folder_name;
          to_post["files"]        = to_archive;
  
          window.status           = "Archiving selected images...";
  
          var as   = new Basis.ajax_scaffold;
          as.alias = "gallery_archive_selected_images";
          as.sid   = this.sid;
          as.url   = this.self_url;
  
          as.pvar  = this;
  
          as.on_success = function (req) {
  
            window.status   = "Done";
            window.location = (window.location+"");

          };
  
          as.post({"to_post":to_post});  

        } // end if

      } // end if

    }, // end archive_selected_images()

    attach_comment_functions: function () {

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          var comment_obj  = MochiKit.DOM.getElement(hex_md5(this.files[i]["url"])+"_comment");
          comment_obj.pvar = this;
          comment_obj.rank = i;
          comment_obj.obj  = this.files[i];

          if (this.logged_in) {

            MochiKit.Signal.connect(comment_obj,"onclick",MochiKit.Base.bind(function () {

              if (MochiKit.DOM.getElement("comment_popup") && MochiKit.DOM.getElement("comment_popup").close) {

                MochiKit.DOM.getElement("comment_popup").close();

              } // end if

              var comment_popup = Basis.popup({"id"           : "comment_popup",
                                               "window_title" : "Set Comment",
                                               "html"         : '<textarea id="image_comment" class="Basis.gallery.image.container.comment_textarea">'+decodeBase64(this.obj["comment"])+'</textarea>'
                                             });

              var dim           = MochiKit.Style.getElementDimensions(this);

              Basis.align_element_to_element("comment_popup",this,"center");

              MochiKit.DOM.getElement("comment_popup").comment_obj = this;

              MochiKit.DOM.getElement("comment_popup").close       = MochiKit.Base.bind(function () {
      
                if ((this.comment_obj.obj["comment"]) != encodeBase64(MochiKit.DOM.getElement("image_comment").value)) {

                  log("saving comment to image "+this.comment_obj.obj["id"]);

                  this.comment_obj.obj["comment"] = encodeBase64(MochiKit.DOM.getElement("image_comment").value);
                  this.comment_obj.pvar.save_image_comment(this.comment_obj.rank);

                } // end if
    
                MochiKit.Signal.disconnectAll(this);
                delete Basis.misc_vars.popups[this.pindex];
                MochiKit.DOM.removeElement(this.id);
      
              },MochiKit.DOM.getElement("comment_popup"));

            },comment_obj));

            MochiKit.Signal.connect(comment_obj,"onmouseenter",MochiKit.Base.bind(function () {
  
              MochiKit.DOM.addElementClass(this,"Basis.gallery.image.container.comment_truncated.over");
  
            },comment_obj));
  
            MochiKit.Signal.connect(comment_obj,"onmouseleave",MochiKit.Base.bind(function () {
  
              MochiKit.DOM.removeElementClass(this,"Basis.gallery.image.container.comment_truncated.over");
  
            },comment_obj));

          } else {

            if (decodeBase64(comment_obj.obj["comment"]).length >= 30) {

              MochiKit.Signal.connect(comment_obj,"onclick",MochiKit.Base.bind(function (e) {
  
                if (MochiKit.DOM.getElement("comment_popup") && MochiKit.DOM.getElement("comment_popup").close) {
  
                  MochiKit.DOM.getElement("comment_popup").close();
      
                } // end if
                
                Basis.misc_vars["Basis.bgallery.open_comment"] = this.id;
  
                var comment_popup = Basis.popup({"id"    : "comment_popup",
                                                 "bare"  : true,
                                                 "style" : "width: 200px; text-align: center;",
                                                 "html"  : decodeBase64(this.obj["comment"]).replace(/\n/g,"<br>")
                                               });
  
                var dim           = MochiKit.Style.getElementDimensions(this);
  
                Basis.align_element_to_element("comment_popup",this,"center");
                Basis.align_element_to_element("comment_popup",this,"top_to_top");
  
                if (!this.clickoff) {
  
                  this.clickoff = MochiKit.Signal.connect(document.body,"onclick",MochiKit.Base.bind(function(e) {
     
                    var element = MochiKit.DOM.getElement("comment_popup");
                    var target  = e.target();
      
                    if (element && target && (element != target) && (target != this) && !MochiKit.DOM.isChildNode(target,element) && !MochiKit.DOM.isChildNode(target,this) && (this.id == Basis.misc_vars["Basis.bgallery.open_comment"])) {
      
                      MochiKit.Signal.disconnect(this.clickoff);
                      element.close();
  
                      this.clickoff = null;
      
                    } // end if
  
                  },this));
  
                } // end if
  
              },comment_obj));
  
              MochiKit.Signal.connect(comment_obj,"onmouseenter",MochiKit.Base.bind(function () {
    
                MochiKit.DOM.addElementClass(this,"Basis.gallery.image.container.comment_truncated.over");
    
              },comment_obj));
    
              MochiKit.Signal.connect(comment_obj,"onmouseleave",MochiKit.Base.bind(function () {
    
                MochiKit.DOM.removeElementClass(this,"Basis.gallery.image.container.comment_truncated.over");
    
              },comment_obj));

            } // end if

          } // end if

        } // end if

      } // end for

    }, // end attach_comment_functions()

    attach_preview_functions: function () {

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          var obj = MochiKit.DOM.getElement(hex_md5(this.files[i]["url"])+"_src");

          if (obj) {

            obj.pvar   = this;
            obj.phash  = hex_md5(this.files[i]["url"]);
            obj.pimage = MochiKit.Base.bind(function () {

              return this.pvar.find_index_by(this.phash,"hash");

            },obj);

            MochiKit.Signal.connect(obj,"onclick",MochiKit.Base.bind(function () {

              if (this.pvar && this.pvar.slideshow && this.pvar.slideshow.compile_non_immersive) {

                this.pvar.slideshow.compile_non_immersive(this.pimage());

              } // end if

            },obj));

          } // end if

        } // end if

      } // end for

    }, // end attach_preview_functions()

    attach_selection_functions: function () {

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          var obj = MochiKit.DOM.getElement(hex_md5(this.files[i]["url"])+"_selected");

          if (obj) {

            obj.pvar = this.files[i];

            MochiKit.Signal.connect(obj,"onclick",MochiKit.Base.bind(function () {

              this.pvar.checked = (this.checked) ? true : false;

            },obj));

          } // end if

        } // end if

      } // end for

    }, // end attach_selection_functions()

    clean_up_drags: function () {

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          if (this.files[i]["draggable"] && this.files[i]["draggable"].destroy) {

            this.files[i]["draggable"].destroy();

          } // end if

          if (this.files[i]["droppable"] && this.files[i]["droppable"].destroy) {

            this.files[i]["droppable"].destroy();

          } // end if

        } // end if

      } // end for

    }, // end clean_up_drags()

    compile: function () {

      this.clean_up_drags();

      var output = "";

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          output += this.image_html(i);

        } // end if

      } // end for

      this.output = '<ul class="Basis.gallery.images">' + output + '</ul>';

      if (this.parent_element && this.parent_element.innerHTML) {

        this.parent_element.innerHTML = this.output;

      } // end if

      this.attach_comment_functions();
      this.attach_selection_functions();
      this.attach_preview_functions();

      this.list = MochiKit.DOM.getFirstElementByTagAndClassName("ul", "Basis.gallery.images", this.parent_element);

      if (this.logged_in) {

        this.initialize_drag_and_drop();

      } // end if

      this.slideshow.preload_image(0);

    }, // end compile()

    create_slideshow: function () {

      this.slideshow = new Basis.bgallery.slideshow(this);

    }, // end create_slideshow()

    delete_selected_images: function() {

      var to_delete = new Array();

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          if (this.files[i].checked == true) {

            to_delete[to_delete.length] = this.files[i]["id"];

          } // end if

        } // end if

      } // end for

      if (to_delete.length>0) {

        var to_post        = new Object();
        to_post["files"]   = to_delete;

        window.status = "Deleting selected images...";

        var as   = new Basis.ajax_scaffold;
        as.alias = "gallery_delete_selected_images";
        as.sid   = this.sid;
        as.url   = this.self_url;

        as.pvar  = this;

        as.on_success = function (req) {

          window.status   = "Done";
          window.location = (window.location+"");

        };

        as.post({"to_post":to_post});  

      } // end if

    }, // end delete_selected_images()

    find_index_by: function (data,type) {

      if (data && type) {

        for (var i in this.files) {
  
          if (this.is_file(this.files[i])) {
  
            switch (type) {
  
              case "hash":
  
                if (hex_md5(this.files[i]["url"])==data) {
  
                  return i;
  
                } // end if
  
                break;
  
              case "id":
  
                if (this.files[i]["id"]==data) {
  
                  return i;
  
                } // end if
  
                break;
  
            } // end switch
  
          } // end if
  
        } // end for

      } // end if

      return -1;

    }, // end find_index_by_hash()

    image_html: function (rank) {

      var html = false;

      if (rank && this.files[rank]) {

        var image   = this.files[rank];
        var hash    = hex_md5(image["url"]);
        var comment = decodeBase64(image["comment"]);
        comment     = (comment.length < 30) ? (comment) : (comment.substring(0,27)+"...");

        if (!comment && this.logged_in) {

          comment = "Click to add a comment";

        } // end if

        if (this.logged_in) {

          var container_title = "<table width=\"100%\"><tr><td>"+ ((image["filename"].length > 23) ? (image["filename"].substring(0,20)+"...") : image["filename"]) +"</td><td style=\"text-align: right;\"><input type=\"checkbox\" id=\""+ hash +"_selected\" class=\""+ image["reference"] +"\"></td></table>";

        } else {

        //var container_title = ""; // ((image["filename"].length > 23) ? (image["filename"].substring(0,20)+"...") : image["filename"]);
          var container_title = "<table width=\"100%\"><tr><td>&nbsp;</td><td style=\"text-align: right;\"><input type=\"checkbox\" id=\""+ hash +"_selected\" class=\""+ image["reference"] +"\"></td></table>";
          var container_title = "<table width=\"100%\"><tr><td class=\"Basis.gallery.image.filename\">"+ ((image["filename"].length > 23) ? (image["filename"].substring(0,20)+"...") : image["filename"]) +"</td><td style=\"text-align: right;\"><input type=\"checkbox\" id=\""+ hash +"_selected\" class=\""+ image["reference"] +"\"></td></table>";

        } // end if

        var html    = '<li id="'+ hash +'" class="Basis.gallery.image">\
                        <table border="0" cellpadding="0" cellspacing="0" width="100%" class="Basis.gallery.image.container no_select">\
                           <tr>\
                             <td class="Basis.gallery.image.container.handle" '+((this.logged_in) ? ("") : ("style=\"display: none;\""))+'>&nbsp;</td>\
                           </tr>\
                           <tr>\
                             <td class="Basis.gallery.image.container.container">\
                               <div class="Basis.gallery.image.container.title">'+ container_title +'</div>\
                               <table border="0" cellpadding="0" cellspacing="0" width="100%">\
                                 <tr>\
                                   <td class="Basis.gallery.image.container.thumbnail"><img id="'+hash+'_src" class="Basis.gallery.image.container.image" src="'+ ((image["has_thumb"]) ? (image["url"]+".thumb") : (image["url"])).replace('#','%23') +'"></td>\
                                 </tr>\
                               </table>\
                               <div id="'+ hash +'_comment" class="Basis.gallery.image.container.comment_truncated">'+ comment +'</div>\
                             </td>\
                           </tr>\
                         </table>\
                       </li>';

      } // end if

      return html;

    }, // end image_html()

    initialize_drag_and_drop: function () {

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          var hash = hex_md5(this.files[i]["url"]);
          var obj  = MochiKit.DOM.getElement(hash);

          if (obj) {

            this.files[i]["draggable"] = new MochiKit.DragAndDrop.Draggable(hash, {
  
              "gallery"      : this,
              "revert"       : true,
              "ghosting"     : false,
              "handle"       : "Basis.gallery.image.container.handle",
              "starteffect"  : function () {},
              "endeffect"    : function () {}
  
            });
  
            this.files[i]["droppable"] = new MochiKit.DragAndDrop.Droppable(hash, {
  
              "gallery"      : this,
              "hoverclass"   : "Basis.gallery.image.to_drop",
              "accept"       : ["Basis.gallery.image"],
              "ondrop"       : MochiKit.Base.bind(this.on_drop,this)
  
            });

          } // end if

        } // end if

      } // end for

    }, // end initialize_drag_and_drop()

    is_file: function (array) {

      if (array && array["id"] && array["filename"] && array["url"]) {

        return true;

      } else {

        return false;

      } // end if

    }, // end is_file()

    on_drop: function (element,dropElt) {

      var from = this.find_index_by(element.id,"hash");
      var to   = this.find_index_by(dropElt.id,"hash");

      Basis.array_insert(this.files,to,this.files[from]);

      if (from > to) { 

        delete this.files[(eval(from)+1)];

      } else {

        delete this.files[from];

      } // end if

      this.update_internal_order();
      this.update_list_order();

      this.save_rankings();

    }, // end on_drop()

    rotate_selected_images: function (angle) {

      var to_rotate = new Array();

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          if (this.files[i].checked == true) {

            to_rotate[to_rotate.length] = {"id":this.files[i]["id"],"angle":angle};

          } // end if

        } // end if

      } // end for

      if (to_rotate.length>0) {

        var to_post      = new Object();
        to_post["files"] = to_rotate;

        window.status    = "Rotating selected images...";

        var as   = new Basis.ajax_scaffold;
        as.alias = "gallery_rotate_selected_images";
        as.sid   = this.sid;
        as.url   = this.self_url;

        as.pvar  = this;

        as.on_success = function (req) {

          window.status   = "Done";
          window.location.reload();

        };

        as.post({"to_post":to_post});  

      } // end if

    }, // end rotate_selected_images()

    save_image_comment: function (rank) {

      if (rank && this.files[rank]) {

        var image   = this.files[rank];
        var hash    = hex_md5(image["url"]);

        var to_post = {"id"      : image["id"],
                       "comment" : decodeBase64(image["comment"])};

        window.status = "Saving image comment...";

        var as   = new Basis.ajax_scaffold;
        as.alias = "gallery_save_image_comment";
        as.sid   = this.sid;
        as.url   = this.self_url;

        as.pvar  = this;

        as.on_success = function (req) {

          this.pvar.compile();
  
          window.status = "Done";

        };

        as.post({"to_post":to_post});  

      } // end if

    }, // end save_image_comment()

    save_rankings: function () {

      var to_post       = new Object();
      to_post["images"] = new Object();

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          to_post["images"][i] = this.files[i]["id"];

        } // end if

      } // end for

      window.status = "Saving gallery rankings...";

      var as   = new Basis.ajax_scaffold;
      as.alias = "gallery_save_rankings";
      as.sid   = this.sid;
      as.url   = this.self_url;

      as.pvar  = this;

      as.on_success = function (req) {

        window.status = "Done";

      };

      as.post({"to_post":to_post});

    }, // end save_rankings()
/*
    toggle_uploader: function () {

      var obj = MochiKit.DOM.getElement("uploader_container");

      if (!obj) {

        var uploader = new MochiKit.DOM.DIV({"id"    : "uploader_container",
                                             "style" : "display:none; width:650px; height:340px; position: absolute; background-color: #FFFFFF; background-image: url(images/images/no_flash.gif); background-repeat: no-repeat; cursor: pointer;"
                                            }," ");

        MochiKit.Signal.connect(uploader, "onclick", function () {

          window.open("http://www.adobe.com/go/getflashplayer");

        });

        document.body.appendChild(uploader);

        var obj = MochiKit.DOM.getElement("uploader_container");

        Basis.center_element(obj);

        obj.style.display = "inline";

        var so = new SWFObject("twg_flash_uploader3.swf", "mymovie", "650", "340", "8", "#ffffff");
        so.useExpressInstall("expressinstall.swf");
        so.addVariable("path_reference", this.path_reference);
        so.addVariable("PHPSESSID", this.sid);
        so.addVariable("cookie_name", this.cookie_name);
        so.addVariable("cookie_value", Basis.get_cookie(this.cookie_name));
        so.write("uploader_container");

      } else {

        MochiKit.DOM.removeElement("uploader_container");

      } // end if

    }, // end toggle_uploader()
*/
    toggle_uploader: function () {

      var obj = MochiKit.DOM.getElement("uploader_container");

      if (!obj) {

        var uploader = DIV({"id"    : "uploader_container",
                            "style" : "display: none; width: 650px; height: 340px; position: absolute; background-color: #FFFFFF; background-image: url(images/images/no_flash.gif); background-repeat: no-repeat; cursor: pointer;"
                           },
                         MochiKit.DOM.createDOM("embed", {"id"        : "uploader_container_flash_container",
                                                          "name"      : "uploader_container_flash_container",
                                                          "src"       : "twg_flash_uploader4.swf",
                                                          "type"      : "application/x-shockwave-flash",
                                                          "height"    : "340",
                                                          "width"     : "650",
                                                          "quality"   : "high",
                                                          "bgcolor"   : "#ffffff",
                                                          "style"     : "",
                                                          "flashvars" : "path_reference="+ this.path_reference +
                                                                        "&PHPSESSID="+ this.sid +
                                                                        "&cookie_name="+ this.cookie_name +
                                                                        "&cookie_value="+ Basis.get_cookie(this.cookie_name)
                                                         }
                         )
                       );

        Basis.signal_handler.connect(uploader, "onclick", function () {

          window.open("http://www.adobe.com/go/getflashplayer");

        }, null, false);

        document.body.appendChild(uploader);

        Basis.center_element(uploader);

        uploader.style.display = "";

// NOTE: THESE KEY EVENTS DON'T CLEAR, AND IN THIS CASE IS A TEMPORARY KEY ACTION THAT SHOULD CLEAR ONCE WE'RE NOT IN THIS PART OF THE CODE ANYMORE

        Basis.key_handler.register_key_event("KEY_ESCAPE", "down", bind(function() {

          Basis.remove_element(this);

        }, uploader));

        Basis.updated_live_dom();

      } else {

        Basis.remove_element("uploader_container");

      } // end if

    }, // end toggle_uploader()

    update_internal_order: function () {

      var temp = [];
      var x    = 0;

      for (var i in this.files) {

        if (this.is_file(this.files[i])) {

          temp[x] = this.files[i];

          x++;

        } // end if

      } // end for

      this.files = temp;

    }, // end update_internal_order()

    update_list_order: function () {

      if (this.list && this.list.childNodes) {

        var temp = [];

        for (var i in this.list.childNodes) {
  
          var index   = this.find_index_by(this.list.childNodes[i].id,"hash");

          temp[index] = this.list.childNodes[i];

        } // end for

      	while (this.list.hasChildNodes()) {
      
      	  this.list.removeChild(this.list.firstChild);
      
      	} // end while

        for (var x=0; x<Basis.array_length(temp); x++) {

          if (temp[x] && temp[x].id) {

            this.list.appendChild(temp[x]);

          } // end if

        } // end for

      } // end if

    } // end update_list_order()

  }; // end class Basis.bgallery.gallery

  // =====================================================

  Basis.bgallery.slideshow = function (gallery) {

    this.__init__(gallery);

  }; // end slideshow()

  Basis.bgallery.slideshow.prototype = {

    __init__: function (gallery) {

      this.gallery               = gallery;
      this.interval              = 3.0;
      this.showing               = 0;
      this.paused                = false;

      this.background_element    = "Basis.bgallery.slideshow.background_element";
      this.controls_element      = "Basis.bgallery.slideshow.controls_element";
      this.comment_element       = "Basis.bgallery.slideshow.comment_element";
      this.image_element_a       = "Basis.bgallery.slideshow.image_element_a";
      this.image_element_b       = "Basis.bgallery.slideshow.image_element_b";
      this.current_image_element = this.image_element_a;

      this.immersion_mode        = true;

      this.ticker                = new Basis.ticker();
      this.ticker.interval       = this.interval;
      this.ticker.tick_do        = MochiKit.Base.bind(function () { this.tick(); },this);

    }, // end __init__()

    compile: function () {

      if (this.gallery.files.length > 0) {

        this.done();

        this.default_values();

        this.create_background();
        this.create_image_elements();
        this.create_comment_element();
        this.create_controls();
        this.show_controls();
        this.preload_image(0);
        this.show_image();
  
        this.play();

      } // end if

    }, // end compile()

    compile_non_immersive: function (image_id) {

      if (this.gallery.files.length > 0) {

        this.done();

        this.default_values();

        this.showing        = Number(image_id);
        this.immersion_mode = false;

        this.create_background();
        this.create_image_elements();
        this.create_comment_element();
        this.create_controls();
        this.show_controls();
        this.show_image();
  
        this.play();
        this.pause();

      } // end if
  
    }, // end compile_non_immersive()

    default_values: function () {

      this.showing         = 0;
      this.paused          = false;
      this.interval        = 3.0;
      this.immersion_mode  = true;

      this.ticker.interval = this.interval;

    }, // end default_values()

    remove_background: function () {

//    if (this.immersion_mode) {

        var obj = MochiKit.DOM.getElement(this.background_element);

        if (obj) {

          MochiKit.DOM.removeElement(obj);

        } // end if

//    } // end if

      Basis.unhide_all_object_elements();

    }, // end remove_background()

    create_background: function () {

      Basis.hide_all_object_elements();

//    if (this.immersion_mode) {

        var obj = MochiKit.DOM.getElement(this.background_element);
  
        if (!obj) {
  
          var element = new MochiKit.DOM.DIV({"id":this.background_element,"style":"display: none; background-color: #000000; position: absolute;"},null);
  
          document.body.appendChild(element);
  
          if (!this.immersion_mode) {

            MochiKit.Style.setOpacity(element, 0.75);

          } // end if

        } // end if

        var obj = MochiKit.DOM.getElement(this.background_element);
  
        if (obj) {
  
          MochiKit.DOM.currentDocument().body.style.overflow = "hidden";
  
          var screend      = MochiKit.Style.getViewportDimensions();
          var scroll       = Basis.scroll_coords();
    
          obj.style.width  = screend.w;
          obj.style.height = screend.h;
    
          MochiKit.Style.setElementPosition(obj,{"x" : scroll.x,
                                                 "y" : scroll.y
                                                });
  
          obj.style.display = "";
   
        } // end if

//    } // end if

      if (!MochiKit.DOM.currentDocument().slideshow_resize) {

        MochiKit.DOM.currentDocument().slideshow_resize = MochiKit.Signal.connect(window,"onresize",MochiKit.Base.bind(function () {

          this.create_background();
          this.position_controls();

        },this));

      } // end if

    }, // end create_background()

    create_image_elements: function () {

      var class_name = "";

      if (!this.immersion_mode) {

        class_name = "Basis.popup.container";

      } // end if

      var obj = MochiKit.DOM.getElement(this.image_element_a);

      if (!obj) {

        var element = new MochiKit.DOM.DIV({"id":this.image_element_a,"class":class_name,"style":"display: none; position: absolute;"},null);
        document.body.appendChild(element);

      } // end if

      var obj = MochiKit.DOM.getElement(this.image_element_a);

      if (obj) {

        MochiKit.Style.setOpacity(obj,0);
        obj.style.display = "";

      } // end if

      var obj = MochiKit.DOM.getElement(this.image_element_b);

      if (!obj) {

        var element = new MochiKit.DOM.DIV({"id":this.image_element_b,"class":class_name,"style":"display: none; position: absolute;"},null);
        document.body.appendChild(element);

      } // end if

      var obj = MochiKit.DOM.getElement(this.image_element_b);

      if (obj) {

        MochiKit.Style.setOpacity(obj,0);
        obj.style.display = "";

      } // end if

      if (!MochiKit.DOM.currentDocument().slideshow_recenter_resize) {

        MochiKit.DOM.currentDocument().slideshow_recenter_resize = MochiKit.Signal.connect(window,"onresize",MochiKit.Base.bind(function () {

          Basis.center_element(this.image_element_a);
          Basis.center_element(this.image_element_b);

        },this));

      } // end if

      if (!MochiKit.DOM.currentDocument().slideshow_recenter_onscroll) {

        MochiKit.DOM.currentDocument().slideshow_recenter_onscroll = MochiKit.Signal.connect(window,"onscroll",MochiKit.Base.bind(function () {

          MochiKit.Signal.signal(window,"onresize");

        },this));

      } // end if

    }, // end create_image_elements()

    remove_image_elements: function () {

      var obj = MochiKit.DOM.getElement(this.image_element_a);

      if (obj) {

        MochiKit.DOM.removeElement(obj);

      } // end if

      var obj = MochiKit.DOM.getElement(this.image_element_b);

      if (obj) {

        MochiKit.DOM.removeElement(obj);

      } // end if

    }, // end remove_image_elements()

    create_comment_element: function () {

      var obj = MochiKit.DOM.getElement(this.comment_element);

      if (!obj) {

        var element = new MochiKit.DOM.DIV({"id":this.comment_element,"class":"Basis.popup.container Basis.gallery.slideshow.comment.container","style":"display: none; position: absolute;"},null);
        document.body.appendChild(element);

      } // end if

      var obj = MochiKit.DOM.getElement(this.comment_element);

      if (obj) {

        MochiKit.Style.setOpacity(obj,0);
        obj.style.display = "";

      } // end if

      if (!MochiKit.DOM.currentDocument().slideshow_realign_comment_resize) {

        MochiKit.DOM.currentDocument().slideshow_realign_comment_resize = MochiKit.Signal.connect(window,"onresize",MochiKit.Base.bind(function () {

          Basis.align_element_to_element(this.comment_element,this.controls_element,"center");
          Basis.align_element_to_element(this.comment_element,this.controls_element,"bottom_to_top",{"y":-20});

        },this));

      } // end if

      if (!MochiKit.DOM.currentDocument().slideshow_realign_comment_onscroll) {

        MochiKit.DOM.currentDocument().slideshow_realign_comment_onscroll = MochiKit.Signal.connect(window,"onscroll",MochiKit.Base.bind(function () {

          MochiKit.Signal.signal(window,"onresize");

        },this));

      } // end if

    }, // end create_comment_element()

    remove_comment_element: function () {

      var obj = MochiKit.DOM.getElement(this.comment_element);

      if (obj) {

        MochiKit.DOM.removeElement(obj);

      } // end if

    }, // end remove_comment_element()

    show_comments: function (rank) {

      var image = null;

      if (!rank) {

        image = this.gallery.files[this.showing];

      } else {

        image = this.gallery.files[rank];

      } // end if

      if (image) {

        var obj = MochiKit.DOM.getElement(this.comment_element);
  
        if (obj) {
  
          if (obj.effect && obj.effect.cancel) {
  
            obj.effect.cancel();
  
          } // end if
  
          var fade_duration = 1;
          var to_opacity    = 0.75;

          if (!this.immersion_mode) {

            fade_duration = 0;
            to_opacity    = 1;

          } // end if

          MochiKit.Style.setOpacity(obj,0);
          obj.style.display = "";

          obj.innerHTML = decodeBase64(image["comment"]).replace(/\n/g,"<br>");
          obj.effect    = MochiKit.Visual.appear(obj,{"duration":fade_duration,"from":0,"to":to_opacity});
  
        } // end if

        Basis.align_element_to_element(this.comment_element,this.controls_element,"center");
        Basis.align_element_to_element(this.comment_element,this.controls_element,"bottom_to_top",{"y":-20});

      } // end if

    }, // end show_comments()

    hide_comments: function () {

      var obj = MochiKit.DOM.getElement(this.comment_element);

      if (obj) {

        if (obj.effect && obj.effect.cancel) {

          obj.effect.cancel();

        } // end if

        var fade_duration = 1;

        if (!this.immersion_mode) {

          fade_duration = 0;

        } // end if

        obj.effect = MochiKit.Visual.fade(obj,{"duration":fade_duration});

      } // end if

    }, // end hide_comments()

    play: function () {

      if (this.paused) {

        this.next();

      } // end if

      this.paused  = false;
      this.ticker.start();

      this.show_interval();

    }, // end play()

    pause: function () {

      if (!this.paused) {

        this.paused = true;
        this.ticker.cancel();

        this.show_interval();

      } else {

        this.play();

      } // end if

    }, // end pause()

    done: function () {

      this.paused = true;
      this.ticker.cancel();

      this.remove_background();
      this.remove_image_elements();
      this.remove_comment_element();
      this.remove_controls();

      MochiKit.DOM.currentDocument().body.style.overflow = "";

      if (MochiKit.DOM.currentDocument().slideshow_resize) {

        MochiKit.Signal.disconnect(MochiKit.DOM.currentDocument().slideshow_resize);
        MochiKit.DOM.currentDocument().slideshow_resize = null;

      } // end if

      if (MochiKit.DOM.currentDocument().slideshow_recenter_resize) {

        MochiKit.Signal.disconnect(MochiKit.DOM.currentDocument().slideshow_recenter_resize);
        MochiKit.DOM.currentDocument().slideshow_recenter_resize = null;

      } // end if

      if (MochiKit.DOM.currentDocument().slideshow_recenter_onscroll) {

        MochiKit.Signal.disconnect(MochiKit.DOM.currentDocument().slideshow_recenter_onscroll);
        MochiKit.DOM.currentDocument().slideshow_recenter_onscroll = null;

      } // end if

      if (MochiKit.DOM.currentDocument().slideshow_realign_comment_resize) {

        MochiKit.Signal.disconnect(MochiKit.DOM.currentDocument().slideshow_realign_comment_resize);
        MochiKit.DOM.currentDocument().slideshow_realign_comment_resize = null;

      } // end if

      if (MochiKit.DOM.currentDocument().slideshow_realign_comment_onscroll) {

        MochiKit.Signal.disconnect(MochiKit.DOM.currentDocument().slideshow_realign_comment_onscroll);
        MochiKit.DOM.currentDocument().slideshow_realign_comment_onscroll = null;

      } // end if

    }, // end done()

    show_interval: function () {

      var obj = MochiKit.DOM.getElement("Basis.gallery.slideshow.controls.interval_text");

      if (obj) {

        if (!this.paused) {

          obj.innerHTML = this.interval + " second" + ((this.interval==1) ? "" : "s") + " : ["+(this.showing+1)+" / "+(this.gallery.files.length)+"]";

        } else {
  
          obj.innerHTML = ((this.immersion_mode) ? ("Paused : ") : ("")) + "["+(this.showing+1)+" / "+(this.gallery.files.length)+"]";

        } // end if

      } // end if

    }, // end show_interval()

    show_image: function (rank) {

      var image   = null;
      var showing = null;

      if (!rank) {

        showing = this.showing;

      } else {

        showing = rank;

      } // end if

      image = this.gallery.files[showing];

      if (image) {

        var image_element    = MochiKit.DOM.getElement(this.current_image_element);
        var opposite_element = MochiKit.DOM.getElement( ((image_element.id == this.image_element_a) ? (this.image_element_b) : (this.image_element_a)) );

        if (image_element && opposite_element) {

          this.preload_image(this.next_image_rank());

          if (opposite_element.effect && opposite_element.effect.cancel) {

            opposite_element.effect.cancel();

          } // end if

          if (image_element.effect && image_element.effect.cancel) {

            image_element.effect.cancel();

          } // end if

          var fade_duration = 1;

          if (!this.immersion_mode) {

            fade_duration = 0;

          } // end if

          opposite_element.effect = MochiKit.Visual.fade(opposite_element,{"duration" : fade_duration});

          MochiKit.Style.setOpacity(image_element,0);

          image_element.innerHTML = '<a href="'+(image["url"]).replace('#','%23')+'" target="_new"><img id="Basis.bgallery.slideshow.image.'+showing+'" border="0" src="'+(image["url"]+((image["has_medium"]) ? (".medium") : (""))).replace('#','%23')+'" width="'+image["dimensions"]["w"]+'" height="'+image["dimensions"]["h"]+'"></a>';

          var obj = MochiKit.DOM.getElement("Basis.bgallery.slideshow.image."+showing);

          if (obj) {

            if (image["image"] && image["image"].src) {

              obj.src = image["image"].src;

            } // end if

          } // end if

          Basis.center_element(image_element);

          image_element.effect = MochiKit.Visual.appear(image_element,{"duration"    : fade_duration,
                                                                       "afterFinish" : MochiKit.Base.bind(function () {
                        
                                                                                         this.current_image_element = ((image_element.id == this.image_element_a) ? (this.image_element_b) : (this.image_element_a));
                        
                                                                                       },this)
                                                                      });

          if (image["comment"]) {

            this.show_comments(rank);

          } else {

            this.hide_comments();

          } // end if

          this.show_interval();

        } // end if

      } // end if

    }, // end show_image()

    previous: function () {

      if (this.paused) {

        this.showing = this.previous_image_rank();
  
        this.show_image();

      } // end if

    }, // end previous()

    next: function () {

      if (this.paused) {

        this.showing = this.next_image_rank();
  
        this.show_image();

      } // end if

    }, // end next()

    first: function () {

      if (this.paused) {

        this.showing = 0;

        this.show_image();

      } // end if

    }, // end first()

    last: function () {

      if (this.paused) {

        this.showing = (this.gallery.files.length - 1);

        this.show_image();

      } // end if

    }, // end last()

    faster: function () {

      if (this.interval && ((this.interval - 1) >= 1)) {

        this.interval--;

      } else {

        this.interval = 1;

      } // end if

      this.ticker.interval = this.interval;

      this.show_interval();

    }, // end faster()

    slower: function () {

      if (this.interval && ((this.interval + 1) <= 15)) {

        this.interval++;

      } else {

        this.interval = 15;

      } // end if

      this.ticker.interval = this.interval;

      this.show_interval();

    }, // end slower()

    show_controls: function () {

      var obj = MochiKit.DOM.getElement(this.controls_element);

      if (obj) {

        if (obj.effect && obj.effect.cancel) {

          obj.effect.cancel();

        } // end if

        obj.effect = MochiKit.Visual.appear(obj,{"duration":0.5});

      } // end if

    }, // end show_controls()

    hide_controls: function () {

      var obj = MochiKit.DOM.getElement(this.controls_element);

      if (obj) {

        if (obj.effect && obj.effect.cancel) {

          obj.effect.cancel();

        } // end if

        if (this.immersion_mode) {

          obj.effect = MochiKit.Visual.fade(obj,{"duration":0.5,"to":0.25}); // ,"afterFinish":MochiKit.Base.bind(function () { MochiKit.Style.setOpacity(this,0); this.style.display = ""; },obj)});

        } // end if

      } // end if

    }, // end hide_controls()

    create_controls: function () {

      var obj = MochiKit.DOM.getElement(this.controls_element);

      if (!obj) {

        var element = new MochiKit.DOM.DIV({"id":this.controls_element,"style":"display: none; position: absolute;"},null);

        document.body.appendChild(element);

      } // end if

      var obj = MochiKit.DOM.getElement(this.controls_element);

      if (obj) {

        if (this.immersion_mode) {

          obj.innerHTML = '\
\
          <div id="Basis.gallery.slideshow.controls.container" class="Basis.gallery.slideshow.controls.container">\
            <table border="0" cellspacing="0" width="100%" class="Basis.gallery.slideshow.controls" align="center">\
            	<tr>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.slower();" border="0" src="images/images/default_icons/delete.gif" width="16" height="16"></td>\
            		<td width="40" align="left" style="padding-left: 5px;">Slower</td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.faster();" border="0" src="images/images/default_icons/add.gif" width="16" height="16"></td>\
            		<td width="40" align="left" style="padding-left: 5px;">Faster</td>\
            		<td id="Basis.gallery.slideshow.controls.interval_text" align="center"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.first();" border="0" src="images/images/default_icons/control_start_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.previous();" border="0" src="images/images/default_icons/control_rewind_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.play();" border="0" src="images/images/default_icons/control_play_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.pause();" border="0" src="images/images/default_icons/control_pause_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.pause();" border="0" src="images/images/default_icons/control_stop_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.next();" border="0" src="images/images/default_icons/control_fastforward_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.last();" border="0" src="images/images/default_icons/control_end_blue.gif" width="16" height="16"></td>\
            		<td width="32" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.done();" border="0" src="images/images/default_icons/cancel.gif" width="16" height="16"></td>\
            	</tr>\
            </table>\
          </div>';

        } else {

          obj.innerHTML = '\
\
          <div id="Basis.gallery.slideshow.controls.container" class="Basis.gallery.slideshow.controls.container">\
            <table border="0" cellspacing="0" width="100%" class="Basis.gallery.slideshow.controls" align="center">\
            	<tr>\
            		<td id="Basis.gallery.slideshow.controls.interval_text" align="center"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.first();" border="0" src="images/images/default_icons/control_start_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.previous();" border="0" src="images/images/default_icons/control_rewind_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.done();" border="0" src="images/images/default_icons/control_stop_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.next();" border="0" src="images/images/default_icons/control_fastforward_blue.gif" width="16" height="16"></td>\
            		<td width="16" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.last();" border="0" src="images/images/default_icons/control_end_blue.gif" width="16" height="16"></td>\
            		<td width="32" align="center"><img style="cursor: pointer;" onclick="Basis.misc_vars.gallery.slideshow.done();" border="0" src="images/images/default_icons/cancel.gif" width="16" height="16"></td>\
            	</tr>\
            </table>\
          </div>';

        } // end if

        if (!document.slideshow_escape) {

          document.slideshow_escape = MochiKit.Signal.connect(document, 'onkeydown', MochiKit.Base.bind(function(e) {

            if (e.key() && (e.key().string == "KEY_ESCAPE")) {

              this.done();

            } // end if

          }, this));

        } // end if

        MochiKit.Style.setOpacity(obj,0);
        obj.style.display = "";

        this.position_controls();

        var tobj = MochiKit.DOM.getElement("Basis.gallery.slideshow.controls.container");

        if (tobj) {

          if (!tobj.event_mouseenter) {

            tobj.event_mouseenter = MochiKit.Signal.connect(tobj,"onmouseenter",MochiKit.Base.bind(function () {

              if (this.signal_show_controls && this.signal_show_controls.cancel) {

                this.signal_show_controls.cancel();

                this.signal_show_controls = null;

              } // end if

              this.show_controls();

            },this));

          } // end if

          if (!tobj.event_mouseleave) {

            tobj.event_mouseleave = MochiKit.Signal.connect(tobj,"onmouseleave",MochiKit.Base.bind(function () {

              if ((!this.signal_show_controls) || (this.signal_show_controls && this.signal_show_controls.fired)) {

                if (this.signal_show_controls) {

                  this.signal_show_controls = null;

                } // end if

                this.signal_show_controls = MochiKit.Async.callLater(1,MochiKit.Base.bind(function () {

                  this.hide_controls();

                },this));

              } // end if

            },this));

          } // end if

        } // end if

      } // end if

    }, // end create_controls()

    position_controls: function () {

      var obj = MochiKit.DOM.getElement(this.controls_element);

      if (obj) {

        Basis.center_element(obj);

        var vdim   = MochiKit.DOM.getViewportDimensions();
        var edim   = MochiKit.Style.getElementDimensions(obj);
        var epos   = MochiKit.Style.getElementPosition(obj);
        var scroll = Basis.scroll_coords();

        MochiKit.Style.setElementPosition(obj,{"x":epos.x,"y":(vdim.h - edim.h - 20 + scroll.y)});

      } // end if

    }, // end position_controls()

    remove_controls: function () {

      var obj = MochiKit.DOM.getElement(this.controls_element);

      if (obj) {

        MochiKit.DOM.removeElement(obj);

      } // end if

    }, // end remove_controls()

    tick: function () {

      if ((this.showing || (this.showing == 0)) && ((this.showing + 1) <= this.gallery.files.length)) {

        this.showing++;

      } else {

        this.showing = 0;

      } // end if

      this.show_image(this.showing);

    }, // end tick()

    previous_image_rank: function () {

      if ((this.showing || (this.showing == 0)) && ((this.showing - 1) >= 0)) {

        return (this.showing - 1);

      } else {

        return (this.gallery.files.length - 1);

      } // end if

    }, // end previous_image_rank()

    next_image_rank: function () {

      if ((this.showing || (this.showing == 0)) && ((this.showing + 1) < this.gallery.files.length)) {

        return (this.showing + 1);

      } else {

        return 0;

      } // end if

    }, // end next_image_rank()

    preload_image: function (rank) {

      if (rank || (rank == 0)) {

        if (this.gallery.files[rank] && !this.gallery.files[rank]["image"]) {

          this.gallery.files[rank]["image"]     = new Image();
          this.gallery.files[rank]["image"].src = (this.gallery.files[rank]["url"]+(this.gallery.files[rank]["has_medium"] ? (".medium") : (""))).replace('#','%23');

          return true;

        } // end if

      } // end if

      return false;

    } // end preload_image()

  }; // end class Basis.bgallery.slideshow
