var IAEdit =
{
  swfu:null,  // JS object to our ShockWave Flash Uploader
  efftp:null, // JS ptr to FileTreePanel thingy (so we can "refresh" it as needed)
  setupDone:false,
  flashsetup:false,

  serverSF:'http://www.archive.org',
  phpDir:'/', // may be like "/~tracey/" instead for dev
  datanodeUrl:'SET-LATER', //eg: "http://ia311012.us.archive.org"
  dirnumber:'', //used in "edit" mode to upload directly to dir item is on

  DBUG:0, // may be like "tracey"

  filesUploaded:0,

  // related to ways a user cannot or chooses not to use the flash method...
  noflash:false,
  noflashnolike:false,
  linux:(navigator.userAgent.indexOf('Linux')>=0 ||
         navigator.userAgent.indexOf('Unix')>=0),
  firefox:(navigator.userAgent.indexOf('Firefox/')>=0),

  lastTitle:'', // last Title seen in form elements (set during focus)
  lastLMAID:'', // last LMA ID computed from form elements (set during focus)
  gottenID:'',
  

  create:function(DBUG)
  {
    this.DBUGME(DBUG);
    this.verb = 'create';
    this.iid = 'UNTITLED';

    if (!this.setupDone)
    {
      this.log("fetching resources up for you");

      var o=document.getElementById('spanButtonPlaceHolder');
      o.innerHTML = '<center><img src="'+this.serverSF+
    '/upload/ext/resources/images/default/grid/wait.gif"/></center>';
      
      
      
      var ins=document.getElementById('begPgSpcr');
      ins.style.position = 'relative';

      var instrux=document.createElement('div');
      instrux.innerHTML = '<div style="z-index:10000; font-size:90%; padding: 5 10 7 10; position:absolute; top:-1px; right:3px; width:150px; height:110px; background-color:#ccc; border-style: solid solid outset inset; border-width: 2 2 5 5; border-color: #999 #999 #888 #888;">Upload books, video, images, and audio that you have the right to share.  Press the [Share] button above to select file(s).<br/><a href="http://www.archive.org/about/faqs.php#Uploading_Content"><img src="/images/question.gif"/></a> <a href="'+this.serverSF+'/about/faqs.php#Uploading_Content">About uploading...</a><div style="font-size:80%; margin-top:4px; text-align:right; ">(prefer to <a onclick="return IAEdit.nolikeflash();" href="http://www.archive.org/about/javascript-required.htm">not use flash</a>?)</div></div>';
      ins.appendChild(instrux);

      var addmore=document.createElement('div');
      addmore.innerHTML = '<div id="addmore" style="position:absolute; top:150px; right:3px; width:150px;"><img src="/images/star.png"/> You may add more files or retry files that error by pressing the [Share] button above again.</div>';
      ins.appendChild(addmore);

      this.loads(0);
    }
  },



  // NOTE: we get passed in some of the various <div> identfiers that we need
  // to manipulate in our various functions...
  edit:function(iid, MAX_FILESIZE_MB, datanode, DBUG, divStatusID, dirnumber)
  {
    this.DBUGME(DBUG);
    this.verb = 'edit';
    this.iid = iid;
    this.MAX_FILESIZE_MB = MAX_FILESIZE_MB;
    this.datanodeUrl =  'http://'+ datanode;
    if (typeof(dirnumber)!='undefined'  &&  parseInt(dirnumber) >= 0)
      this.dirnumber = dirnumber;

    this.setup(divStatusID);

    if (this.firefox)
    {
      document.getElementById('maxfs').innerHTML = '2.0G';
      this.unhide('firefox');
    }
  },


  DBUGME:function(DBUG)
  {
    if (DBUG  &&  DBUG!='')
    {
      this.DBUG = DBUG;
      this.serverSF     = 'http://www-'+DBUG+'.archive.org';
      this.phpDir       = '/~'+DBUG+'/';
    }
  },
  

  
  // NOTE: only for "create"
  loadmes:[
    // for blue panel look (only *now* needed for "Share" button and fetching
    //                      this now jacks up other existing CSS, so not doing)
    //  '/upload/ext/resources/css/ext-all.css', 
    
    // for HTML for the item metadata form (and some other stuff)
    '/share.php?metadataForm=1&callback=IAEdit.gotMetadataForm',
    // for SWFUpload
    '/upload/default.css',
    '/upload/swfupload.js?v=1.6',
    '/upload/swfupload.queue.js',
    '/upload/fileprogress.js?v=1.4',
    '/upload/handlers.js?v=1.5',
    // for screen dimensions
    '/includes/scriptaculous-js-1.6.2/lib/prototype.js',
    // for flashembed (flash version checking)
    '/flow/flowplayer-3.0.3.min.js'
  ],
  loadmesDone:[],
  loads:function(idx) // NOTE: only for "create"
  {
    // check off prior resource being loaded (1st resource is not applicable 8-)
    if (idx)
    {
      var prev = idx-1;
      if (typeof(this.loadmesDone[prev])!='undefined')
        return; // another event signalling JS/CSS is loaded already fired!
      this.loadmesDone[prev] = true;
      this.log('loaded :'+this.loadmes[prev]);
    }
      
    if (typeof(this.loadmes[idx])!='undefined')
    {
      var load = this.serverSF + this.loadmes[idx];
      this.log('loading resource '+load);
      var suffix = load.substr(load.lastIndexOf('.'));
      var headobj = document.getElementsByTagName("head")[0];
      if (suffix == '.css')
      {
        var obj = document.createElement('link');
        obj.setAttribute('type','text/css');
        obj.setAttribute('rel' ,'stylesheet');
        obj.setAttribute('href', load);
        // hmm does not work (for CSS)...
        //     obj.onload = function() { IAEdit.loads(idx+1); };
        // but since CSS can be loaded in parallel safely, move on to next load...
        headobj.appendChild(obj);
        this.loads(idx+1);
      }
      else
      {
        var obj = document.createElement('script');
        obj.onload        = function(){ IAEdit.loads(idx+1);};
        obj.onstatechange = function(){ IAEdit.loads(idx+1);};     // for IE7 css
        obj.onreadystatechange = function(){ IAEdit.loads(idx+1);};// for IE7 js
        obj.setAttribute('type','text/javascript');
        obj.setAttribute('src', load);
        headobj.appendChild(obj);
      }
    }
    else
    {
      this.loadsDone = true;
      this.isAllLoaded();
    }
  },

  gotMetadataForm:function(stuff) // NOTE: only for "create"
  {
    this.log(stuff);
    this.JS_FIELDS      = stuff.JS_FIELDS;
    this.SUFFIXES       = stuff.SUFFIXES;
    this.metadataForm   = stuff.htm;

    var datanode = this.getCookie('http-uploader');
    if (!datanode)
    {
      alert('Internet Archive Editor requires cookies.  Are cookies turned off?');
      return;
    }
    this.datanodeUrl = 'http://'+ datanode;
    


    // make AJAX call to retrieve 
    var headobj = document.getElementsByTagName("head")[0];         
    var obj = document.createElement('script');
    obj.setAttribute('type','text/javascript');
    obj.setAttribute('src', this.datanodeUrl + this.phpDir + 'edit.php?alreadyUp=1&callback=IAEdit.alreadyUp');
    this.log('getting ' + this.datanodeUrl + this.phpDir + 'edit.php alreadyUp');
    headobj.appendChild(obj);
  },

  alreadyUp:function(stuff) // NOTE: only for "create"
  {
    this.log('loaded alreadyUp');
    this.alreadyUpAry = stuff.alreadyUp;
    this.MAX_FILESIZE_MB= stuff.MAX_FILESIZE_MB;
    this.isAllLoaded();
  },

  isAllLoaded:function() // NOTE: only for "create"
  {
    if (typeof(this.alreadyUpAry)!='undefined'  &&
        typeof(this.loadsDone)!='undefined')
    {
      this.allLoaded();
    }
  },
  
  allLoaded:function() // NOTE: only for "create"
  {
    this.log('all resources loaded');
    if (typeof(this.allLoadedDone)!='undefined')
      return;
    this.allLoadedDone = true;
    
      
    var bodyobj = document.getElementsByTagName("body")[0];
    bodyobj.setAttribute('id','editbody');
    
    // NOTE: id="createPage" has some archive.css rules
    var createPageObj=document.createElement('div');
    createPageObj.setAttribute('id', 'createPage'); 




    this.maxWH(createPageObj);
    createPageObj.innerHTML = this.metadataForm;

    var begPgSpcr=document.getElementById('begPgSpcr');
    begPgSpcr.appendChild(createPageObj);

    
    // make changes to the default "0 files uploaded" divStatus if needed
    if (this.alreadyUpAry.length)
    {
      var prevUpObj = document.getElementById('prevUp');
      var prevUp = '';
      for (var i=0,fi; fi=this.alreadyUpAry[i]; i++)
      {
        var sizeP = fi.indexOf('(');
        //this.log(fi.substr(sizeP+1));
        var pretty = this.prettySize(fi.substr(sizeP+1));
        prevUp += ' '+fi.substr(0,sizeP)+'('+pretty+')<br/>';
      }
      prevUpObj.innerHTML += prevUp;
      prevUpObj.style.display = 'block'; // unhide!
      
      this.divStatusID = 'divStatus';
      this.divStatusPlus(this.alreadyUpAry.length);
    }
    
    
    
    this.setup('divStatus');

    
    this.log("setup for you!");
    if (this.alreadyUpAry.length  ||  this.linux)
      this.showCreatePage();
  },

  showCreatePage:function() // NOTE: only used/does something for "create"
  {
    this.unhide('createPage');
    if (this.linux)
      this.shownoflash();
  },

  // user specifically is opt-ing to NOT use flash
  // (although flash has been detected properly for their browser, etc.)
  nolikeflash:function()
  {
    this.noflashnolike = true;
    if (this.verb=='create')
      this.unhide('createPage');
    this.shownoflash();
    return false;
  },

  shownoflash:function()
  {
    if (this.noflashnolike)
    {
      this.hide('noflashbig');
      this.hide('noflashlinux');
      this.unhide('noflashnolike');
    }
    else if (this.linux)
    {
      this.hide('noflashbig');
      this.unhide('noflashlinux');
      this.hide('noflashnolike');
    }
    else
    {
      this.unhide('noflashbig');
      this.hide('noflashlinux');
      this.hide('noflashnolike');
    }
    
    this.unhide('noflash');
    this.noflash = true;
    var o = document.getElementById('toeditor');
    if (o)
      o.value = '1';
  },
  

  // NOTE: we get passed in some of the various <div> identfiers that we need
  // to manipulate in our various functions...
  setup:function(divStatusID)
  {
    this.divStatusID = divStatusID;

    // Flash uploader stuff from here on down
    if (typeof(flashembed)!='undefined'  &&  !flashembed.isSupported([9,0]))
    {
      var ver = flashembed.getVersion();
      var uhave = (ver=='0,0' ?
                   ' you do not have flash installed or have it disabled' :
                   ' you have version: '+ver+'');
      document.getElementById("uhave").innerHTML = uhave;
      this.unhide("noflashupgrade");
      
      if (this.verb=='create')
        this.unhide("createPage");//make sure user can see "upgrade!" message!

      this.noflashnolike = true;
      this.shownoflash();
    }
    else
    {
      this.setupFlash();
    }
    
    this.setupDone = true;
  },


  setupFlash:function()
  {
    if (this.flashsetup)
      return;
    this.flashsetup = true;

    if (this.linux)
      this.shownoflash();
    

    // flash uploader only tends to work on 1G or less, and fails on 2G+
    this.MAX_FILESIZE_MB = Math.min(2048, parseInt(this.MAX_FILESIZE_MB));

    this.overridesSWFU();

    // NOTE: xxx VERY subtle!!  "location.port" is the current port of the page
    // you be at.  we want to make sure we use the same [server:port] combo
    // as the actual page the flash object is embedded in so that we don't
    // get a security cross-site domain fail!
    var port='';
    if (typeof(location)!='undefined'  &&  typeof(location.port)!='undefined'  &&
        location.port)
    {
      port = parseInt(location.port);
      if (port <= 0  ||  port > 10000) // typically 80 or 80 implied
        port = '';
      else
        port = ':'+port;
    }
    var upload_url = this.datanodeUrl + port + '/edit' + this.dirnumber;//edit.php
    this.log('UU: ' + upload_url);

    this.swfu = new SWFUpload({
      flash_url : this.serverSF + "/upload/swfupload.swf",
      upload_url: upload_url,
      post_params: {"liu":this.getCookie('logged-in-user'),
                    "lis":this.getCookie('logged-in-sig'),
                    "iid":this.iid},
      file_size_limit : this.MAX_FILESIZE_MB + " MB",
      file_types : "*.*",
      file_types_description : "All Files",
      file_upload_limit : 5000,
      file_queue_limit : 0,
      custom_settings : {
        progressTarget : "fsUploadProgress",
        cancelButtonId : "btnCancel"
      },
      debug: false,

      // Button settings
      button_image_url: this.serverSF + "/upload/ia-blank.png", //Relative to Flash file
      button_width: "50",
      button_height: "20",
      button_placeholder_id: "spanButtonPlaceHolder",
      button_text: '<span class="theFont">Share</span>',
      button_text_style: ".theFont { font-size: 16; }",
      button_text_left_padding: 5,
      button_text_top_padding: 1,
   

      // The event handler functions are defined in handlers.js
      queue_complete_handler : null, // IA override from "queueComplete"
      
      file_queued_handler : fileQueued,
      file_queue_error_handler : fileQueueError,
      file_dialog_complete_handler : fileDialogComplete,
      upload_start_handler : uploadStart,
      upload_progress_handler : uploadProgress,
      upload_error_handler : uploadError,
      upload_success_handler : uploadSuccess,
      upload_complete_handler : uploadComplete
      });
  },


  overridesSWFU:function()
  {
    this.FAILS = //NOTE: need to stay synced w/ pet/www/common/Edit.inc
    {
    501 : "No upload found in FILES for Filedata",
    503 : "Upload failed is_uploaded_file test.",
    504 : "File has no name.",
    505 : "File exceeds the maximum allowed size",
    506 : "File size outside allowed lower bound",
    507 : "Invalid file name",
    508 : "File with this name already exists",
    509 : "Invalid file extension",
    510 : "File could not be saved.",
    511 : "POST exceeded maximum allowed size.",
    512 : "Browser cookies did not transfer.  Are cookies enabled?",
    513 : "Upload area full - please try again later",
    
    // these correspond to general php upload errors, 0..6
    520 : "There is no error, the file uploaded with success",
    521 : "The uploaded file exceeds the upload_max_filesize directive in php.ini",
    522 : "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
    523 : "The uploaded file was only partially uploaded",
    524 : "No file was uploaded",
    526 : "Missing a temporary folder"
    };

    
    // override
    SWFUpload.prototype.fileQueueErrorOrig =
    SWFUpload.prototype.fileQueueError;
    SWFUpload.prototype.fileQueueError = function (file, errorCode, message)
    {
      IAEdit.unhide('addmore');
      
      // the "0-byte file" happens for files > 4G (go 32bit, go!)
      if (errorCode == SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE  ||
          errorCode == SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT)
      {
        IAEdit.shownoflash();
      }
      
      this.fileQueueErrorOrig(file, errorCode, message);
    };

    
    // override
    SWFUpload.prototype.fileDialogCompleteOrig =
    SWFUpload.prototype.fileDialogComplete;
    SWFUpload.prototype.fileDialogComplete = function (numFilesSelected,
                                                       numFilesQueued)
    {
      IAEdit.filesUploaded += numFilesQueued;
      if (numFilesSelected > 0)
        IAEdit.showCreatePage();
      this.fileDialogCompleteOrig(numFilesSelected, numFilesQueued);
    }

    
    // override
    SWFUpload.prototype.uploadErrorOrig =
    SWFUpload.prototype.uploadError;
    SWFUpload.prototype.uploadError = function (file, errorCode, message)
    {
      IAEdit.unhide('addmore');
      message = (typeof(IAEdit.FAILS[message])=='undefined' ? message :
                 IAEdit.FAILS[message]);
      this.uploadErrorOrig(file, errorCode, message);
    }


    // override
    SWFUpload.prototype.uploadSuccessOrig =
    SWFUpload.prototype.uploadSuccess;
    SWFUpload.prototype.uploadSuccess = function (file, serverData)
    {
      this.uploadSuccessOrig(file, serverData);

      IAEdit.unhide('addmore');
      IAEdit.divStatusPlus(1);
      IAEdit.mtpick(file.name);
      if (IAEdit.efftp)
        IAEdit.efftp.root.reload();
    }

    
    // override
    FileProgress.prototype.disappear = function () { } // do nothing
  },


  divStatusPlus:function(nFiles)
  {
    var status = document.getElementById(IAEdit.divStatusID);
    var nDone = parseInt(status.innerHTML);
    nDone += nFiles;
    status.innerHTML = nDone + ' file'+(nDone==1?'':'s')+' uploaded.';
  },
  

  titleFocus:function()
  {
    this.lastTitle = document.getElementById('title').value;
    //this.log('LT ==> ['+this.lastTitle+']');
  },


  
  // When user picks a title for their new item, we need to kick off AJAX request
  // to return us an appropriate available identifier.
  getIdentifier:function(title)
  {
    if (!title)
      return;
    if (title == this.lastTitle)
      return; // no change
    


    if (!this.setupDone)
    {
      this.log('reloop for body load...');
      if (typeof(this.setupRetry)=='undefined')
        this.setupRetry = 0;
      this.setupRetry++;
      // give up after 40 iterations of 1/2 sec wait/retry (20 sec)
      if (this.setupRetry < 40)
        window.setTimeout("IAEdit.getIdentifier('"+title+"')", 500);
      return; 
    }

    for (var i=1; i < 10; i++) this.unhide('hide'+i); // unhide sections
    this.feedback('checking if identifier is free... <img src="'+this.serverSF+
                  '/upload/ext/resources/images/default/grid/wait.gif"/>');
    
    
    // make AJAX call to retrieve 
    var headobj = document.getElementsByTagName("head")[0];         
    var obj = document.createElement('script');
    obj.setAttribute('type','text/javascript');
    obj.setAttribute('src', this.datanodeUrl + this.phpDir + 'share.php?getid=' + encodeURIComponent(title) + '&callback=IAEdit.gotIdentifier');
    headobj.appendChild(obj);
  },

  
  // We got the identifier that we should use
  gotIdentifier:function(ret)
  {
    if (!ret.success)
    {
      this.feedback('There was an error with your entry:<br/>' + ret.error);
      return;
    }


    // Show them an identifier that is available based on their title entry
    this.feedback('Identifier "'+ret.identifier+'" is available.');


    // for form doublechecking on "create" page to make sure the user hasn't
    // raced from the title (or LMA fields) filling out to the submit button
    // WITHOUT waiting for the "checking for identifier..." to return and
    // assign an identifier!
    this.gottenID = ret.identifier;
    
    
    document.getElementById('myid1').innerHTML =
    '<br/> called "'+ret.identifier+'",';
    


    if (this.efftp)
      this.efftp.root.reload(); // xxxx only really need for when returning/reloading form and may have updated EditCookie to last "available" identifier...
  },


  feedback:function(str)
  {
    var f;
    f = document.getElementById('feedback');    if (f) f.innerHTML = str;
    f = document.getElementById('feedbackLMA'); if (f) f.innerHTML = str;
  },
  

  // etree / LMA functions
  LMAtoggle:function()
  {
    if (document.getElementById('concertpost').innerHTML=='?')
    {
      document.getElementById('concertpre').innerHTML='This is';
      document.getElementById('concertpost').innerHTML='.';
      document.getElementById('lma').value = '1';
    }
    else
    {
      document.getElementById('concertpre').innerHTML='Is this';
      document.getElementById('concertpost').innerHTML='?';
      document.getElementById('lma').value = '';
    }
    this.toggle('lmaform');
    this.toggle('testbox');
    return this.toggle('nonlma');
  },

  LMAmakeID:function()
  {
    var abbrev = document.getElementById('show_abbrev').value;
    var date   = document.getElementById('show_date'  ).value;
    var rest   = document.getElementById('show_rest'  ).value;

    if (!abbrev  ||  !date)
      return false;

    if (rest)
      rest = rest.replace(/^\.+/, '');
    
    if (!date.match(/^((19)|(20))\d\d\-\d\d\-\d\d$/))
    {
      alert("date is not proper format of YYYY-MM-DD");
      return false;
    }
      
    var id = abbrev + date + (rest ? '.'+rest : '');
    this.log(abbrev+'/'+date+'/'+rest+'==>'+id);
    return id;
  },

  LMAfocusID:function()
  {
    var id = IAEdit.LMAmakeID();
    this.lastLMAID = (id ? id : '');
  },
  
  LMAcheckID:function()
  {
    var id = IAEdit.LMAmakeID();
    if (!id)
      return false;
    if (this.lastLMAID == id)
      return false; // no change
        
    IAEdit.getIdentifier(id);
    return true;
  },
  

  mtpick:function(fname)
  {
    var elm = document.getElementById('mediatypeSel');
    if (!elm)
      return; // we are in "edit" not "create" mode
    
    if (elm.value != "")
      // leave to what user has picked OR what we auto-picked the first time
      // they browsed for a file
      return; 
    
    
    // use 1st upload file to determine its suffix and thus its mediatype
    var suffix = (fname.substring(fname.lastIndexOf(".")+1)).toLowerCase();

    var mt = null;
    for (var medtype in this.SUFFIXES)
    {
      for (var sfx in this.SUFFIXES[medtype])
      {
        if (sfx == suffix) 
        {
          mt = medtype;
          break;
        }
      }

      if (mt!=null)
        break;
    }
    

    if (mt==null)
      mt = 'other';
    //this.log('['+suffix+'] ==> '+mt);
    IAEdit.mtselect(mt);

    // insert a note about how their mediatype got picked -- though it's likely
    // the "mediatypeSel" div is hidden, that's just fine!
    var o = document.getElementById('mediatypeSel');
    var ap=document.createElement('div');
    ap.setAttribute('style', 'font-style:italic;');
    ap.innerHTML = 'We picked the type of your item based upon the first file you uploaded.<br/>  You may change the type if you wish.'
    o.parentNode.insertBefore(ap, o);
  },



  mtselect:function(mt)
  {
    // first unselect/unhighlight any previous selected mediatype
    for (var medtype in this.SUFFIXES)
    {
      var o = document.getElementById('mt'+ (medtype=='Image' ? 'other':medtype));
      o.style.borderColor     = 'transparent';
      o.style.backgroundColor = 'transparent';
    }

    // now select/highlight the desired mediatype
    // when someone picks a file corresponding to an "Image" mediatype,
    // we don't *show* it as such -- we show it as "other"
    var selectme = (mt=='Image' ? 'other' : mt);
    var o = document.getElementById('mt' + selectme);
    o.style.borderColor    ='gray';
    o.style.backgroundColor='wheat';

    o = document.getElementById('mediatypeSel');
    o.value = mt;

    o = document.getElementById('mytype');
    o.innerHTML = selectme +' item<br/> (<a style="font-size:80%; font-style:italic" onclick="IAEdit.toggle(\'mtsection1\'); IAEdit.toggle(\'mtsection2\'); return IAEdit.toggle(\'mtsection3\')" href="#">not a'+(selectme.match(/^[aeiou]/i)?'n':'')+' "'+selectme+'" item?</a>)';
    o.style.display = 'inline'; //unhide
  },


  testinputs:function()
  {
    var tbox = document.getElementById('testing');
    for (var i=0, check; check=this.JS_FIELDS[i]; i++)
    {
      var elm = document.getElementById(check);
      if (tbox.checked)
      {
        // testing box is checked
        if (elm  &&  !elm.value  &&  check!='title')
          elm.value = 'test item';
      }
      else
      {
        // testing box is NOT checked
        if (elm  &&  elm.value=='test item')
          elm.value = '';
      }
    }
  },


  shareSubmitCheck:function(optval)
  {
    if (this.verb != 'edit')
    {
      if (document.getElementById('lma').value=='1')
      {
        var chex = ['show_abbrev','show_date'];
        for (var i=0, name; name=chex[i]; i++)
        {
          var check = document.getElementById(name);
          if (!check  ||  check.value == '')
          {
            alert('Please add a ' + name.replace(/_/,' '));
            return false;
          }
          else if (name=='show_date')
          {
            if (!check.value.match(/^((19)|(20))\d\d\-\d\d\-\d\d$/))
            {
              alert("date is not proper format of YYYY-MM-DD");
              return false;
            }
          }
        }

        var id = this.LMAmakeID();
        this.log("form elems ID: '"+id+"' vs gottenID: '"+this.gottenID+"'");
        if (id != this.gottenID)
        {
          // that's bad -- likely user hasn't waited for identifier checker to
          // return.  only way this can be OK is if they wanted an identifier
          // like:  "zwan2008-08-18" but that was taken so they got suggested
          // the suffixed version like "zwan2008-08-18_123".
          if (this.gottenID.length <= id.length  ||
              this.gottenID.substr(0,id.length) != id  ||
              !this.gottenID.substr(id.length).match(/^\d+$/))
          {
            // "gottenID" did NOT start with "id" and end with suffix _###
            alert("Please wait for the identifier assignment to finish");
            return false;
          }
        }
      }
      else
      {
        for (var i=0, name; name=this.JS_FIELDS[i]; i++)
        {
          var check = document.getElementById(name);
          if (check.value == '')
          {
            if (name=='subject')
              alert('Please add at least one keyword');
            else
              alert('Please add a ' + name);
            return false;
          }
        }
      }

      if (!this.gottenID)
      {
        alert("Please wait for the identifier assignment to finish");
        return false;
      }
    }
    

    
    // See if they have any files still uploading...
    // NOTE: for people w/ too old flash versions, this.swfu is (still) null
    // NOTE: for people w/ "flash blocker" installed, this.swfu is **NOT** null,
    //       but this.filesUploaded==0
    if (this.filesUploaded  &&  this.swfu)
    {
      var stats = this.swfu.getStats();
      if (stats.in_progress > 0)
      {
        alert('Please wait for your ' + stats.in_progress +
              ' file(s) to finish uploading.');
        return false;
      }
    }

    
    if (this.verb != 'edit')
    {
      // make sure the user has uploaded one (or more) file(s)
      var nDone = parseInt(document.getElementById(this.divStatusID).innerHTML);
      if (nDone==0  &&  !this.noflash)
      {
        alert('Please upload at least one or more files');
        return false;
      }
    }

    if (typeof(optval)!='undefined')
      document.getElementById('submitted').value = optval;

    document.getElementById('shareSubmitForm').submit();
    return true;
  },


  // "waits" for a catalog task to finish, periodically polling server for status.
  //   (by toggling visibility on 2 divs when task is done)
  waitUntilTaskDone:function(task_id, readyupID, waitupID, DBUG)
  {
    if (typeof(this.task_id  )=='undefined')    this.task_id   = task_id;
    if (typeof(this.readyupID)=='undefined')    this.readyupID = readyupID;
    if (typeof(this.waitupID )=='undefined')    this.waitupID  = waitupID;
    if (typeof(DBUG)!='undefined') this.DBUGME(DBUG);
    
    // make AJAX call to retrieve
    var headobj = document.getElementsByTagName("head")[0];         
    var obj = document.createElement('script');
    obj.setAttribute('type','text/javascript');
    obj.setAttribute('src', this.phpDir+'share.php?callback=IAEdit.taskDone&status=' +
                     this.task_id + '&random=' + Math.random());
    headobj.appendChild(obj);
    this.log(obj.getAttribute('src'));
  },

  taskDone:function(resp)
  {
    this.log(resp);
    if (resp == 'done')
    {
      document.getElementById(IAEdit.readyupID).style.display = 'block';
      document.getElementById(IAEdit.waitupID).style.display = 'none';
    }
    else if (resp.match(/^error/))
    {
      document.getElementById(IAEdit.waitupID).innerHTML =
      'ERROR copying item into cluster (' + resp +
      ').  Please wait for an administrator to resolve or you may try a different identifier name and try again...';
    }
    else
    {
      if (typeof(this.wutsleep)=='undefined')
        this.wutsleep = 2000;

      setTimeout("IAEdit.waitUntilTaskDone()", this.wutsleep);
      
      this.wutsleep *= 1.5; // decay rate 1.5!  (sleep more and more each time)
    }
  },


  maxWH:function(obj)
  {
    // bleah find max for all the crappy custom browers possible max dimens 	 
    var maxW = screen.availWidth; 	 
    var maxH = screen.availHeight;
    maxW = 0;//xxxxx
    if (document.body  &&  document.body.offsetWidth)
    { // IE4, IE6
      maxW = Math.max(maxW, document.body.offsetWidth);
      maxH = Math.max(maxH, document.body.offsetHeight);
    } 	 
    if (document.body  &&  document.body.clientwidth)
    { 	 
      maxW = Math.max(maxW, document.body.clientwidth);
      maxH = Math.max(maxH, document.body.clientheight);
    }
    if (window.innerWidth)
    { 	 
      maxW = Math.max(maxW, window.innerWidth); 	 
      maxH = Math.max(maxH, window.innerHeight); 	 
    }

    // prototype.js thing -- now try finding property of the <body> element...
    var bodyobj = document.getElementsByTagName("body")[0];
    if (typeof(bodyobj.getDimensions)!='undefined')// undef function in XP IE7
    {
      var dim = bodyobj.getDimensions();
      maxW = Math.max(maxW, dim.width); 	 
      maxH = Math.max(maxH, dim.height); 	 
    }
    
    
    if (document.body) 	 
    { 	 
      // height is even harder than width, turns out: 	 
      //   http://www.quirksmode.org/viewport/compatibility.html 	 
      maxH = Math.max(maxH, document.body.scrollHeight); 	 
      maxH = Math.max(maxH, document.body.offsetHeight); 	 
      maxW = Math.max(maxW, document.body.scrollWidth); 	 
      maxW = Math.max(maxW, document.body.offsetWidth); 	 
    } 	 
    
    //xxxxx obj.style.width  = maxW; 	 
    obj.style.height = maxH;
  },
    
    
 

  // transforms a file size into a good looking number with reasonable units
  prettySize:function(size)
  {
    size = parseFloat(size);
    
    /**/ if(size<      1024)return size                         +' B' ;//bytes
    else if(size<     10240)return (size/1024).toFixed(2)       +' KB';//precise K
    else if(size<   1048576)return Math.round(size/1024)        +' KB';//K
    else if(size<  10485760)return (size/1048576).toFixed(2)    +' MB';//precise M
    else if(size<1073741824)return Math.round(size/1048576)     +' MB';//M
    
    return (size/1073741824).toFixed(1)+' GB'; // G
  },
  

  log:function(str)
  {
    if (!this.DBUG)
      return; // in production mode!
     
    if (typeof(location)!='undefined'  &&  (location.host.substr(0,4)!='www-'  &&
                                            location.pathname.substr(0,2)!='/~'))
    {
      return; // in production mode!
    }

    if (typeof(document)=='undefined')                    print(str); //SSJS
    else if (navigator.userAgent.indexOf('IE')>=0)        return;//alert(str);//IE
    else if (navigator.userAgent.indexOf('Safari')>=0)    console.log(str);
    else if (navigator.userAgent.indexOf('Firefox')>=0)
    {
      if (typeof(window.console)!='undefined')            window.console.log(str);
    }
  },


  // parse a CGI arg
  arg:function(theArgName)
  {
    sArgs = location.search.slice(1).split('&');
    r = '';
    for (var i=0; i < sArgs.length; i++)
    {
      if (sArgs[i].slice(0,sArgs[i].indexOf('=')) == theArgName)
      {
        r = sArgs[i].slice(sArgs[i].indexOf('=')+1);
        break;
      }
    }
    return (r.length > 0 ? unescape(r).split(',') : '')
  },
  
  

  // modified from: http://www.w3schools.com/JS/js_cookies.asp
  getCookie:function(c_name)
  {
    if (document.cookie.length>0)
    {
      c_start=document.cookie.indexOf(c_name + "=");
      if (c_start!=-1)
      { 
        c_start=c_start + c_name.length+1; 
        c_end=document.cookie.indexOf(";",c_start);
        if (c_end==-1) c_end=document.cookie.length;

        return decodeURIComponent(document.cookie.substring(c_start,c_end).replace(/\+/g,' '));
      } 
    }
    return "";
  },

  unhide:function(i)
  {
    var e=document.getElementById(i);
    if (e) e.style.display = 'block';
    return false;
  },

  
  hide:function(i)
  {
    var e=document.getElementById(i);
    if (e) e.style.display = 'none';
    return false;
  },

  
  toggle:function(i)
  {
    var e=document.getElementById(i);
    if (e)
      e.style.display=(e.style.display!='block'?'block':'none');
    return false;
  }


};
