function Util() {
  throw new Error("Util is a static class. You can't create instances of it.");
}

Util.windowSize = function() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement &&
    ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  return {width: myWidth, height: myHeight};
};

Util.createElement = function(doc,tagName) {
  var newElt = doc.createElement(tagName);
  if (typeof(newElt) != 'object') {newElt = doc.standardCreateElement(tagName);}
  return newElt;
};
  
/**
 * Given an HTMLElement, return the HTMLDocument it belongs to
 */
Util.getEltDoc = function(anElt) {
  if (anElt.ownerDocument) {return anElt.ownerDocument;}
  if (anElt.document) {return anElt.document;}
  return document;
};

/**
 * This method calls document.createElement() to create a new element, and 
 * then initialized the new element with the values provided by the caller.
 *
 * @scope    public class method
 * @param    tagName    The HTML tag for the element ("div", "p", "span", etc.). 
 * @param    cssClassName    Optional. The HTML/CSS class to assign to the new element. 
 * @param    attributesInJson    Optional. A JSON object with additional attributes to set on the new element. 
 * @param    text    Optional. A text string to put in a text node within the new element. 
 * @return   The newly created HTML element.
 */
Util.newElement = function(tagName, cssClassName, attributesInJson, text, style, doc) {

  if (!doc) {doc = document;}
  var newElement = Util.createElement(doc,tagName);
  if (cssClassName) {
    newElement.className = cssClassName;
  }
  if (attributesInJson) {
    for (var key in attributesInJson) {
      if (key == 'id') {
        newElement.id = attributesInJson[key];
      } else {
        if (key == 'jfor') {
          newElement.setAttribute('for', attributesInJson[key]);
        }
        else {
          newElement.setAttribute(key, attributesInJson[key]);
        }
      }
    }
  }
  if (style) {
      for (key in style) {
        if (key == 'cssFloat' && Util.isIE()) {
          newElement.style['styleFloat'] = style[key];
        }
        else {
          newElement.style[key] = style[key];
        }
      }
  }    
  if (text) {
    newElement.appendChild(doc.createTextNode(text));
  }
  return newElement;
};


/**
 * Given an HTML element, we first call document.createElement() to 
 * create a new element, and then call appendChild() to add the new 
 * element to the given element.
 *
 * Example:
 * <pre>
 * var menuUrl = "http://en.wikipedia.org/";
 * var menuText = "Wikipedia";
 * var menuItem = Util.appendNewElement(mainMenu, "li", NavbarView.CSS_CLASS_MENU_ITEM);
 * var link = Util.appendNewElement(menuItem, "a", null, {href: menuUrl}, menuText);
 * </pre>
 *
 * @scope    public class method
 * @param    parentElement    The existing element that we should append the new element to. 
 * @param    tagName    The HTML tag for the element ("div", "p", "span", etc.). 
 * @param    cssClassName    Optional. The HTML/CSS class to assign to the new element. 
 * @param    attributesInJson    Optional. A JSON object with additional attributes to set on the new element. 
 * @param    text    Optional. A text string to put in a text node within the new element. 
 * @return   The newly created HTML element.
 */
Util.appendNewElement = function(parentElement, tagName, cssClassName, attributesInJson, text,style) {
  var doc = Util.getEltDoc(parentElement);
  var newElement = Util.newElement(tagName, cssClassName, attributesInJson, text,style,doc);
  parentElement.appendChild(newElement);
  return newElement;
};


/**
 * Given an HTML element, we first call document.createTextNode() to 
 * create a new text node, and then call appendChild() to add the new 
 * text node to the given element.
 *
 * @scope    public class method
 * @param    parentElement    The existing element that we should append the new element to. 
 * @param    textString    The text string to put in the text node.
 * @return   The newly created text node.
 */
Util.appendNewTextNode = function(parentElement, textString) {

  var doc = Util.getEltDoc(parentElement);
  var newTextNode = doc.createTextNode(textString);
  parentElement.appendChild(newTextNode);
  return newTextNode;
};

Util.blankString = function(str) {
  return !(str && !str.match(/^\s*$/));
};

Element.showHide = function(elt, show) {
  if (show) {Element.show(elt);}
  else {Element.hide(elt);}
};

var StepsWidget = Class.create();
StepsWidget.prototype = {
  initialize: function(element, options) {
    this.element = $(element);
    var baseID = this.element.id;
    options = Object.extend({
      groupClass: baseID+'_step_group',
      headerClass: baseID+'_step_header',
      bodyClass: baseID+'_step_body',
      collapsedClass: 'js_collapsed',
      expandedClass: 'js_expanded'
    },options || {});
    
    if (!this.element) {throw 'StepsWidget element cannot be null';}
    
    this.groupClass = options.groupClass;
    this.bodyClass = options.bodyClass;
    this.headerClass = options.headerClass;
    this.collapsedClass = options.collapsedClass;
    this.expandedClass = options.expandedClass;
    this.steps = $A(this.element.childNodes).collect(function(elt) {
      return (elt.className && Element.hasClassName(elt, options.groupClass) ? elt : null);
    }).compact();
    this.bodies = this.getStepChildrenOfClass(this.bodyClass);
    this.headers = this.getStepChildrenOfClass(this.headerClass);
    var thisObj = this;
    this.headers.each(function(header) {
      Element.addClassName(header, thisObj.collapsedClass);
      Event.observe(header, 'click', function() {thisObj.toggle(header);});
    });
  },
  
  getStepChildrenOfClass: function(classname) {
    var children = $A();
    this.steps.each(function(step) {
      children.push($A(step.childNodes).find(function(child) {
        return child.className && Element.hasClassName(child, classname);}));});
    return children;
  },
  
  toggle: function(selectedHeader, effect) {
    var wasClosed = Element.hasClassName(selectedHeader,this.collapsedClass);
    if (wasClosed) {
      Element.removeClassName(selectedHeader, this.collapsedClass);
      Element.addClassName(selectedHeader, this.expandedClass);
    }
    else {
      Element.removeClassName(selectedHeader, this.expandedClass);
      Element.addClassName(selectedHeader, this.collapsedClass);
    }
    var selectedIndex = this.headers.indexOf(selectedHeader);
    if (effect) {new effect(this.bodies[selectedIndex], {queue: 'end'});}
    else {Element.toggle(this.bodies[selectedIndex]);}
  },
  openStep: function(stepNum, withHighlight) {
    var stepHeader = this.headers[stepNum];
    var wasClosed = Element.hasClassName(stepHeader,this.collapsedClass);
    if (wasClosed) {this.toggle(stepHeader, Effect.Appear);}
		if (withHighlight) {
	    var stepBody = this.bodies[stepNum];
	    new Effect.Highlight(stepBody, {queue: 'end'});
	    new Effect.Highlight(stepBody, {queue: 'end'});
		}
  }
};

var TabbedWidget = Class.create();
TabbedWidget.prototype = {
  initialize: function(element, options) {
    this.element = $(element);
    var baseID = this.element.id;
    options = Object.extend({
      headerUL: baseID+'_tab_header',
      bodyClass: baseID+'_tab_body',
      selectedClass: 'current'
    },options || {});
    
    if (!this.element) {throw 'StepsWidget element cannot be null';}
    
    this.bodyClass = options.bodyClass;
    this.selectedClass = options.selectedClass;
    var headerUL = $(options.headerUL);
    Element.cleanWhitespace(this.element);
    Element.cleanWhitespace(headerUL);
    this.headers = $A( headerUL.childNodes);
    this.bodies = $A(this.element.childNodes).collect(function(elt) {
      return (elt.className && Element.hasClassName(elt, options.bodyClass) ? elt : null);
    }).compact();
    var thisObj = this;
    this.headers.each(function(header) {
      Event.observe(header, 'click', function() {thisObj.select(header);});
    });
  },
  
  select: function(selectedHeader) {
    var selectedClass = this.selectedClass;
    var isSelected = Element.hasClassName(selectedHeader,selectedClass);
    if (!isSelected) {
      this.headers.each(function(header) {
        if (header != selectedHeader) {
          Element.removeClassName(header,selectedClass);
        }
      });
      Element.addClassName(selectedHeader, selectedClass);
      var selectedIndex = this.headers.indexOf(selectedHeader);
      this.bodies.each(function(body, index) {
        if (index == selectedIndex) {
          Element.show(body);
        }
        else {
          Element.hide(body);
        }
      });
    }
  }
};


function appendScript(url) {
  var head = document.getElementsByTagName("head")[0];
  var script = document.createElement("script");
  script.charset = "utf-8";
  script.src = url;
  script.type = 'text/javascript';
  head.appendChild(script);
}

var ImagePicker = Class.create();
ImagePicker.prototype = {
  initialize: function(options) {
    options = Object.extend({
      selectedClass: 'selected',
      searchField: 'image_keywords',
      defaultEngine: 'yahoo'
    }, options || {});
    this.pickerDiv = $(options.pickerDiv);
    this.spinner = $(options.spinner);
    this.selectedClass = options.selectedClass;
    this.currentEngine = options.defaultEngine;
    this.searchField = $(options.searchField);
    this.setupEngineLinks();
  },
  setupEngineLinks: function() {
    var self = this;
    $H(ImageSearcher.engines).keys().each(function(engine) {
      self.setAnEngineLink(engine);
    });
  },
  setAnEngineLink: function(engineStr) {
    var elt = $('more_'+engineStr);
    var self = this;
    if (this.currentEngine == engineStr) {
      elt.onclick = null;
      Element.addClassName(elt, 'current');
    }
    else {
      elt.onclick = function() {self.selectNewEngine(engineStr, true);};
      Element.removeClassName(elt, 'current');
    }
  },
  selectNewEngine: function(engineStr, search) {
    if (engineStr != this.currentEngine) {
      Element.removeClassName(this.searchField, this.currentEngine);
      this.currentEngine = engineStr;
      Element.addClassName(this.searchField, this.currentEngine);
      this.setupEngineLinks();
      if (search) {this.search();}
    }
  },
    
  search: function(options) {
    options = Object.extend({
      engine: this.currentEngine,
      keywords: this.searchField.value
    }, options || {});

    Element.hide('more_image_results');
    Element.hide('previous_image_results');
    if (options.page <= 0) {
      // show popular results instead
      new Ajax.Updater({success:'image_results'}, '/layout/popular', {asynchronous:true});
      return;
    }
    
    if (Util.blankString(options.keywords)) {return;}
    this.searchField.value = options.keywords;
    this.selectNewEngine(options.engine);
    Element.show(this.spinner);
    this.imageSearcher = new ImageSearcher(this, options);
  },
  
  update: function(images, options) {
    Element.hide(this.spinner);
    if (images.length > 0) {
      this.pickerDiv.innerHTML = '';
      var pickerDiv = this.pickerDiv;
      this.images = images;
      var self = this;
      images.each(function(imageInfo) {
        var thumbDiv = Util.appendNewElement(pickerDiv,'div','thumb');
        var link = Util.appendNewElement(thumbDiv,'a', null, {href:'javascript:void(0)'});
        var img = imageInfo.getThumbImage(96,96);
        imageInfo.keywords = options.keywords;
        img.onclick = function() {self.selectImage(this);};
        link.appendChild(img);
      });
      var moreLink = $('more_image_results');
      var newOptions = {keywords: options.keywords, page: options.page+1};
      moreLink.onclick = function() {self.search(newOptions);};
      Element.show('more_image_results');
      var backLink = $('previous_image_results');
      var backOptions = {keywords: options.keywords, page: options.page-1};
      backLink.onclick = function() {self.search(backOptions);};
      Element.show('previous_image_results');
    }
    else {
      this.pickerDiv.innerHTML = 'Sorry, no results found!';
    }
  },
  
  selectImage: function(image) {
    if (this.selectedImage == image) {return;}
    if (this.selectedImage && this.selectedImage.parentNode) {
      Element.removeClassName(this.selectedImage.parentNode, this.selectedClass);
    }
    if (image && image.parentNode) {
      Element.addClassName(image.parentNode, this.selectedClass);
    }
    this.selectedImage = image;

    $('image_url').value = image.imgInfo.url;
    le.setBackgroundForCheck(image.imgInfo);
  },
  updateErr: function(msg) {
    alert(msg);
  }
};

var ImageSearcher = Class.create();
ImageSearcher.engines = {
  yahoo: {
    baseURL: 'http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=clipclip&output=json&results=10&callback=ImageSearcher.updateFunc&query=',
    updateFunc: function(results) {
      var images = [];
      results.ResultSet.Result.each(function(result) {
        if (result.Width >= 300 && result.Height >= 225) {
          images.push(new ImageInfo(result.Title, result.Url, result.Thumbnail.Url,
             result.Width, result.Height, result.Thumbnail.Width, result.Thumbnail.Height));
        }
      });
      this.picker.update(images, this.options);
    },
    pageParameter: function(page) {
      return 'start=' +((page-1)*10+1); // extra parens needed, otherwise will be casted as string
    }
  },
  flickr: {
    baseURL: 'http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=b3c10aaffb08eccf9b3afffa2c66066f&per_page=10&sort=interestingness-desc&format=json&jsoncallback=ImageSearcher.updateFunc&text=',
    updateFunc:  function(results) {
      var errMsg = null;
        try {
          if (results.stat == 'ok') {
            var images = [];
            results.photos.photo.each(function(photo) {
              var imgUrl = 'http://farm' + photo.farm + 
                '.static.flickr.com/'+photo.server+'/'+photo.id+'_'+photo.secret+'.jpg';
              var thumbUrl = 'http://farm' + photo.farm + 
                '.static.flickr.com/'+photo.server+'/'+photo.id+'_'+photo.secret+'_s.jpg';
              images.push(new ImageInfo(photo.title, imgUrl, thumbUrl, 1024, 768, 75, 75));
            });
            this.picker.update(images, this.options);
          }
          else {
            errMsg = results.message;
          }
        }
        catch (e) {
          errMsg = e;
          throw e;
        }
        if (errMsg) {this.picker.updateErr(errMsg);}
    },
    pageParameter: function(page) {
      return 'page='+page;
    }
  },
  google: {
    baseURL: 'http://www.coolchaser.com/background/proxy_mash?keywords=',
    updateFunc: function(returnObj) {
      var images = [];
      returnObj.results.each(function(result) {
        if (result.imageWidth >= 300 && result.imageHeight >= 225) {
          images.push(new ImageInfo(result.displayUrl, result.imageUrl, result.thumbnailUrl,
            result.imageWidth, result.imageHeight, result.thumbnailWidth, result.thumbnailHeight));
        }
      });
      this.picker.update(images, this.options);
    },
    pageParameter: function(page) {
      return 'start=' +((page-1)*10+1); // extra parens needed, otherwise will be casted as string
    }
  }
};

ImageSearcher.prototype = {
  initialize: function (picker, options) {
    this.picker = picker;
    options = Object.extend({
      engine: 'yahoo',
      page: 1
    }, options || {});
    this.options = options;
    var engineObj = ImageSearcher.engines[options.engine];
    ImageSearcher.updateFunc = engineObj.updateFunc.bind(this);
    var searchURL = engineObj.baseURL + encodeURIComponent(options.keywords); 
    if  (options.page) {searchURL += '&'+engineObj.pageParameter(options.page);}
    setTimeout(function() {appendScript(searchURL);}, 10); //ie6 does not like appendscript from link onclick
  }
} ;

var ImageInfo = Class.create();
ImageInfo.prototype = {
  initialize: function(title, url, thumbUrl, width, height, thumbWidth, thumbHeight, backgroundID) {
    this.title = title;
    this.url = url;
    this.thumbUrl = thumbUrl;
    this.width = width;
    this.height = height;
    this.thumbWidth = thumbWidth;
    this.thumbHeight = thumbHeight;
    this.backgroundID = backgroundID;
  },
  getThumbImage: function(idealWidth, idealHeight) {
    var img = new Image();
    img.title = this.title + ': ' + this.width + 'x' + this.height;
    img.imgInfo = this;
    // if at first you don't succeed, try, try again!
    img.errFunc = function() {this.src = this.imgInfo.thumbUrl;};
    img.onerror = function() {setTimeout(img.errFunc.bind(img), Math.floor(Math.random()*100+1));};
    img.src = this.thumbUrl;
    if (this.thumbWidth && this.thumbHeight) {
      this.setThumbImageDimensions(img, idealWidth, idealHeight);
    }
    else {
      var self = this;
      img.onload = function() {
        self.thumbHeight = this.height;
        self.thumbWidth = this.width;
        self.setThumbImageDimensions(this, idealWidth, idealHeight);
      };
    }
    return img;
  },
  setThumbImageDimensions: function(img, idealWidth, idealHeight) {
    if (this.thumbWidth/idealWidth < this.thumbHeight/idealHeight) {
      img.width = idealWidth;
      img.height = this.thumbHeight*idealWidth/this.thumbWidth;
      var offset = (img.height-idealHeight)/2;
      img.style.marginTop = -offset + 'px';
      img.style.marginLeft = '0px';
      img.style.clip = 'rect(' + offset + 'px, ' + idealWidth + 'px, ' + (offset+idealHeight) + 'px, 0px)';
    }
    else {
      img.height = idealHeight;
      img.width = this.thumbWidth*idealHeight/this.thumbHeight;
      var offset = (img.width-idealWidth)/2;
      img.style.marginTop = '0px';
      img.style.marginLeft = -offset+'px';
      img.style.clip = 'rect(0px, ' + (offset+idealWidth) + 'px, ' + idealHeight + 'px, ' + offset + 'px)';
    }
    img.style.width = img.width + 'px';
    img.style.height = img.height + 'px';
    //img.style.position = 'absolute';
  }
};

var LayoutPreview = Class.create();
LayoutPreview.prototype = {
  initialize: function(themes, options) {	  
    this.insertionID = options.insertionID;
    this.frame = $(options.frame);
    this.themes = $A(themes);
    this.backgroundElt = $(options.background);
    this.selectedTheme = null;
    window.onresize = this.onResize.bind(this);
	
    this.isProfilePreview = true;
    var self = this;	
/*
    this.css_selectors.each(function(keyVal) {
      var name = keyVal[0];
      var inputSrc, inputChange;

      if (keyVal[1].usage == 'boolean') {
        inputSrc = 'checked';
        inputChange = 'click';
      }
      else {
        inputSrc = 'value';
        inputChange = 'change';
      }

      //$('layout_'+name).value = 
	  $(name)[inputSrc] = keyVal[1].default_val;
      $(name)['on'+inputChange] = function() {
		  this.selectedTheme = keyVal[1].main_css;
        self.updateStyle(); // true);
        //$('layout_'+name).value = $(name)[inputSrc];
      };
    });
*/	
  },
  selectBackground: function(imgInfo) { 
      var img = imgInfo.checkImage;
    this.backgroundImageInfo = imgInfo;
    this.backgroundElt.innerHTML = '';
    var bkgndImage = this.backgroundImage = Util.newElement('img'); //new Image();
    bkgndImage.src = img.src;
    bkgndImage.width = 1024;
    bkgndImage.height = img.height*1024/img.width;
    this.usingDiv = false;
	
//    this.updateBackgroundPosition();
    if (img.src == '')
		return;

	window.document.body.style.background = "url('" + img.src + "') fixed center no-repeat";
	document.forms["form1"].results.value = "<a href=http://www.whymyspace.com><img src=" + img.src + "></a>";
	document.forms["form1"].bbcode.value = "[URL=http://www.whymyspace.com][IMG]" + img.src + "[/IMG][/URL]";

document.forms["form1"].myspace.value = "<style type=text/css> body { background-color: rgb(255,255,255); background-image: url(" + img.src + "); background-position: top center; background-repeat: no-repeat; background-attachment: fixed; }</style><a href=http://www.whymyspace.com>Code Generators</a>";

//    this.backgroundElt.appendChild(bkgndImage);
//	document.body.style.background = "url('" + img.src + "') fixed center no-repeat";
/*
    $A(this.backgroundElt.childNodes).each(function(child) {Element.remove(child);});
    if (img.width < 1000) {
      var bkgndImage = this.backgroundImage = new Image();
      bkgndImage.src = img.src;
      bkgndImage.width = 1024;
      bkgndImage.height = img.height*1024/img.width;
      this.usingDiv = true;
      this.updateBackgroundPosition();
      this.backgroundElt.appendChild(bkgndImage);
      document.body.style.background = "url('" + img.src + "') fixed center no-repeat";
	  
		document.forms["form1"].results.value = "<a href=http://www.trymyspace.com><img src=http://" + bkgndImage.src + "></a>";
    }
    else {
      document.body.style.background = "url('" + img.src + "') fixed center no-repeat";
      this.usingDiv = false;
      this.backgroundImage = null;
	  document.forms["form1"].results.value = "<a href=http://www.sevenmilesearch.com><img src=" + img.src + "></a>";
    }
*/
  },
  updateBackgroundPosition: function() {
    if (this.backgroundImage) {
      var windSize = Util.windowSize();
      var pos = $('background_pos').value;
      switch (pos) {
        case 'top':
          this.backgroundElt.style.top = 0;
          break;
        case 'center':
          var top = (windSize.height - this.backgroundImage.height)/2;
          this.backgroundElt.style.top = Math.round(top) + 'px';
          break;
        case 'bottom':
          var top = (windSize.height - this.backgroundImage.height);
          this.backgroundElt.style.top = Math.round(top) + 'px';
          break;
      }
      var left = (windSize.width - this.backgroundImage.width)/2;
      this.backgroundElt.style.left = Math.round(left) + 'px';
    }
    return '';
  },
/*
  updateBackgroundPosition: function() {
    var windSize = Util.windowSize();
    var left = (windSize.width - this.backgroundImage.width)/2;
    var top = (windSize.height - this.backgroundImage.height)/2;
    this.backgroundElt.style.top = Math.round(top) + 'px';
    this.backgroundElt.style.left = Math.round(left) + 'px';
  },
*/
  onResize: function() {
    if (this.usingDiv) {this.updateBackgroundPosition();}
  },
  _createStyleElt: function() {
    if (!this.styleElt) {
      var frameDoc = this.frame.contentWindow.document;
      this.preStyleDiv = frameDoc.getElementById(this.insertionID);
      this.styleElt = frameDoc.createElement('style');
      this.styleElt.setAttribute('type','text/css');
    }
  }
/*
  _getStyleElt: function() {
    return this._getPreviewElt(this.insertionID);
  },
  _getPreviewElt: function(id) {
    var frameDoc = this.frame.contentWindow.document;
    return frameDoc.getElementById(id);
  }
*/
};

var ThemePicker = Class.create();
ThemePicker.prototype = {
  initialize: function(mainDiv,themes) {
    var mainDiv = this.mainDiv = $(mainDiv);
    var thisObj = this;
		this.selectedImageLink = null;
		this.selectedImageLinkClass = 'selected';
    if (!this.mainDiv) {throw 'theme picker has no mainDiv!';}
    $A(themes).each(function(aTheme) {
      var themeDiv = Util.appendNewElement(mainDiv, 'div', 'theme');
      var imageLink = Util.appendNewElement(themeDiv, 'a', null, {href:'javascript:void(0)'});
      Util.appendNewElement(imageLink,'img',null,
        {src:'/images/themes/thumb_'+aTheme.name+'.gif', title:aTheme.name+' theme'});
      var pElt = Util.appendNewElement(themeDiv,'p');
      var textLink = Util.appendNewElement(pElt, 'a', null, {href:'javascript:void(0)'}, aTheme.name);
      var selectFunc = function() {thisObj.selectTheme(aTheme.id, imageLink);};
      Event.observe(imageLink, 'click', selectFunc);
      Event.observe(textLink, 'click', selectFunc);
    });
  },
  selectTheme: function(themeID, imageLink) {
		if (imageLink != this.selectedImageLink) {
	    le.setTheme(themeID);
			if (imageLink) {Element.addClassName(imageLink,this.selectedImageLinkClass);}
			
			if (this.selectedImageLink) {Element.removeClassName(this.selectedImageLink, this.selectedImageLinkClass);}
			this.selectedImageLink = imageLink;
		}
  }
};
      
var Slider = Class.create();
Slider.prototype = {
  initialize: function(mainDiv) {
    this.out = false;
    this.mainDiv = $(mainDiv);
    this.tab = $(arguments[1]);
    var myThis = this;
    $A(arguments).each( function(elt, index) {
      if (index != 0) {
        Event.observe(elt, 'click', myThis.toggle.bindAsEventListener(myThis));
      }
    });
  },
  
  toggle: function() {
    if (!this.disabled && !this.tempDisabled) {
      this.tempDisabled = true;
      var moveByAmt = this.mainDiv.offsetWidth*(this.out ? -1 : 1);
      var self = this;
      new Effect.MoveBy(this.mainDiv,0, moveByAmt,{afterFinish:self.enable.bind(self), queue:'end'});
      this.out = !this.out;
    }
  },
  open: function() {
    this.disabled = false;
    if (!this.out) {this.toggle();}
  },
  enable: function() {
    this.tempDisabled = false;
    if (this.intervalHdl) {
      clearInterval(this.intervalHdl);
      this.intervalHdl = null;
    }
    else if (!this.out && this.tab) {
      var self = this;
      this.intervalHdl = setInterval(function() {new Effect.Shake(self.tab, {queue:'end'});},30000);
    }
  },
  disable: function() {
    if (this.out) {this.toggle();}
    this.disabled = true;
  }
};

var StatusNotifier = Class.create();
StatusNotifier = {
  initialize: function(mainDiv, spinner, msg, closeLink, slider) {
    this.mainDiv = $(mainDiv);
    this.spinner = $(spinner);
    this.message = $(msg);
    this.close = $(closeLink);
    this.close.onclick = function() {StatusNotifier.hideMessage();};
    this.notificationLevel = 0;
    this.slider = slider;
    Element.hide(mainDiv);
  },
  showMessage: function(newMsg, options) {
    options = options || {};
    this.message.innerHTML = newMsg;
    Element.showHide(this.spinner, options.showSpinner);
    Element.showHide(this.close, options.closeBox);
    this.notificationLevel++;
    new Effect.Appear(this.mainDiv, {queue: 'front'});
  },
  hideMessage: function(msg) {
    if (msg) {this.message.innerHTML = msg;}
    new Effect.Fade(this.mainDiv, {queue: 'end'});
    this.slider.open();
    this.notificationLevel--;
  }
};
  
var LayoutEditor = Class.create();
LayoutEditor.prototype = {
  initialize: function(themes, preview_options) {
    this.themes = themes;

    var slider = this.slider = new Slider('sb', 'js_customise_btn', 'js_hide_link');
	
    StatusNotifier.initialize('status','status_spinner','status_text', 'status_close', slider);
    this.stepWidget = new StepsWidget('js_editor');

    this.preview = new LayoutPreview(themes, {background:'bg', frame:'preview', insertionID:'c2_anchor'});
		
    this.imgPicker = new ImagePicker({pickerDiv:'image_results', spinner:'image_search_wait'});

    this.update_form = document.forms.update_form;
    this.background = null;
    this.theme = null;

    setTimeout(function() {slider.toggle();}, 500);
	
	window.document.body.style.background = "url(http://s172.photobucket.com/albums/w38/woodsix/th_Image120land.gif) fixed center no-repeat";
  },
  searchThemes: function() {
    $('theme_choice').getElementsBySelector('a').each(function(elt) {
      elt.removeClassName('current');
    });
    $('search_choice').show();
    le.themePicker.setFetchUrlSuffix('search' + this.search_theme_suffix, $('search_tag').value);
    try {urchinTracker('/themes/search?' + encodeURIComponent($('search_tag').value));} catch (e) {}
    this.themePicker.fetchThemes();
  },
  doImageSearch: function(options) {
    this.imgPicker.search(options);
  },
  updateThemes: function(themes, own) {
    themes =  $A(themes).collect(function(t) {return new Theme(t);});
    this.preview.updateThemes(themes, own);
    if (own) {this.userThemePicker.updateThemes(themes);}
    else {this.themePicker.updateThemes(themes);}
  },
  showAutoUpdate: function() {
    var msg = '';
    if (Util.blankString(this.update_form['layout[theme_id]'].value)) {
      this.stepWidget.openStep(0, true);
      msg += "<p>&middot; Please choose a theme before updating the profile.</p>";
    }
    if (msg) {
      msg = '<h1>Oops!</h1>' + msg;
      StatusNotifier.showMessage(msg, {closeBox: true});
      return;
    }
    this.slider.disable();
    StatusNotifier.showMessage('', {showSpinner: false});
    $('status_text').innerHTML = '';
    $('status_text').appendChild($('auto_update'));
  },
  cancelAutoUpdate: function() {
    $('auto_update_parent').appendChild($("auto_update"));
    StatusNotifier.hideMessage();
  },
  updateProfile: function() {
    var msg = '';
    if (Util.blankString(this.update_form.email.value)) {
      msg += "Email can't be blank.<br />";
    }
    if (Util.blankString(this.update_form.password.value)) {
      msg += "Password can't be blank.\n";
    }
    if (msg) {
      $('auto_warning').innerHTML = msg;
      new Effect.Highlight('auto_warning');
      return;
    }
    $('auto_update_parent').appendChild($('auto_update'));
    msg = 'Updating profile now...<br /> This may take a while...';
    if (this.background && !this.update_form['layout[background_id]'].value) {
      // get server to fetch background and return background_id
      msg += "<br />...uploading your background...";
      new Ajax.Request('/background/fetch',
        {method:'post', asynchronous:true, evalScripts:true,
        parameters:this.background.getFormParameters(),
        onFailure: this._xhrError.bind(this), onSuccess: this._backgroundFetched.bind(this)});
    }
    else {
      msg += "<br />...inserting your layout...";
      new Ajax.Request('/layout/insert',
        {method:'post', asynchronous:true, evalScripts:true, parameters:Form.serialize(this.update_form),
        onFailure: this._xhrError.bind(this)});
    }
    StatusNotifier.showMessage(msg, {showSpinner: true});
  },
  setBackgroundForCheck: function(imgInfo, dontShowMsg) {
    this._temp_image = imgInfo;
    this._checkImage(dontShowMsg);
  },
  setTheme: function(themeID) {
    this.preview.selectTheme(themeID);
    this.update_form['layout[theme_id]'].value = themeID;
    this.theme = themeID;
  },
  showUserThemes: function() {
    if (!this.userThemePicker) {
      this.userThemePicker = new ThemePicker('user_theme_picker','more_user_themes','prev_user_themes','my_theme_wait');
      this.userThemePicker.setFetchUrlSuffix('own');
      this.userThemePicker.fetchThemes();
    }
  },
	showHelp: function() {
		Element.hide('sb');
		Element.show('help_screen');
		Element.show('editor_screen');
	},
	closeHelp: function() {
		Element.show('sb');
		Element.hide('help_screen');
		Element.hide('editor_screen');		
	},
/*
	tweakInit: function() {
	  if (!this._tweakLoaded) {
	    this._tweakLoaded = true;
  	  ['dragdrop', 'slider', 'builder', 'yahoo.color', 'colorPicker'].each(function(file) {
  	    appendScript('/javascripts/'+ file + '.js');
	    });
	  }
  },
*/
	setPreviewToProfile: function(setToProfile) {
	  this.preview.setPreviewToProfile(setToProfile);
	},
	updatePreviewSrc: function() {
	  this.setPreviewToProfile(this.profilePreview);
	},
  _checkImage: function(dontShowMsg) {
    if (!dontShowMsg) {
      StatusNotifier.showMessage('Please wait... checking to see if full image of ' +
        this._temp_image.title + ' is available.', {showSpinner: true});
    }
    var testImage = this._temp_image.checkImage = new Image();
    testImage.onload = this._imageLoaded.bind(this);
    testImage.onerror = this._imageError.bind(this);
    testImage.onabort = this._imageAborted.bind(this);
    testImage.src = this._temp_image.url; 
  },
  _imageLoaded: function() {
    if (!this._temp_image) {return;} // this means some other background has later been selected
    StatusNotifier.hideMessage('Full image found! Loading image now...');
    var url = this._temp_image.url;
    this.background = this._temp_image;
/*
    this.update_form['layout[keywords]'].value = this.background.getKeywords();
    this.update_form['layout[background_id]'].value = this.background.backgroundID || '';
*/
    this.preview.selectBackground(this._temp_image);
    this._temp_image = null;
  },
  _imageError: function() {
    if (!this._temp_image) {return;} // this means some other background has later been selected
    StatusNotifier.showMessage('<h1>Oops</h1><p>sorry: full image of ' + this._temp_image.title + ' is not available</p>',
      {closeBox: true});
    this._temp_image = null;
  },
  _imageAborted: function() {
    if (!this._temp_image) {return;} // this means some other background has later been selected
    StatusNotifier.showMessage('<h1>Oops</h1><p>sorry: loading of image ' + this._temp_image.title + ' has been aborted</p>');
    this._temp_image = null;
  },
  _backgroundFetched: function(xhr) {
    this.update_form['layout[background_id]'].value = xhr.responseText;
    this.updateProfile();
  },
  _xhrError: function(xhr) {
    StatusNotifier.showMessage('<h1>Oops</h1><p>sorry: an error occurred while trying to communicate to the Coolchaser server.</p>' +
      xhr.statusText + ' ' + xhr.responseText + ' ' + xhr.status, {closeBox: true});
  }
};

function mySpaceAction(action,id, notice) {
  var form = $('myspace_login');
  form.onsubmit = function () {
    new Ajax.Request(action, {asynchronous:true, evalScripts:true,
      onLoading:function(request){$('use_submit').disabled=true;$('inserting_now').show();$('error').hide();},
      onComplete: function() {$('use_submit').disabled=false;}, parameters:Form.serialize(this)});
    return false;
  };
  form.id.value = id;
  var doBlogCheckbox = $('proto_blog');
  form.blog.value = doBlogCheckbox && doBlogCheckbox.checked;
  if (notice) {form.notice.value = notice;}
  $('inserting_now').hide();
  $('prompt').show();
  return false;
}

Uploader = {
  showStep1: function() {
    $('upload_1').value='';
    $('upload_1').show();
    $('upload_2').hide();
  },
  showStep2: function() {
    $('upload_1').hide();
    $('upload_2').show();
    var titleInput = $('upload_title');
    titleInput.value = 'click to add title';
    titleInput.show();
    titleInput.addClassName('add_title');
    $('upload_btn').show();
    $('upload_wait').hide();
    $('upload_name').innerHTML = $('upload_1').value.match(/(\/|\\)([^\/\\]*)$/)[2];
  },
  success: function() {
    $('upload_btn').hide();
    $('upload_title').hide();
    $('upload_wait').hide();
  }    
};

Nabbr = {
  doProfilePreview: function() {
    if (Prototype.Browser.IE) {
      $('nabbr').show();
    }
    else {
      $('no_nabbr').show();
    }
  }
};
