/* Globally useful methods */

function toMoney(cents, format) {
  if(format) {
    return format.gsub(/\{\{\s*(\w+)\s*\}\}/, function(element) {
      switch(element[1]) {
      case 'amount':
        return floatToString(cents/100.0, 2);
      case 'amount_no_decimals':
        return floatToString(cents/100.0, 0);
			case 'amount_with_comma_separator':
			  return floatToString(cents/100.0, 2).gsub(/\./, ',');
      case 'currency':
        return '';      
      }
    });
  }
  else {
    return floatToString(cents/100.0, 2);
  }
}

function floatToString(numeric, decimals) {  
  var amount = numeric.toFixed(decimals).toString();  
  if(amount.match(/^\.\d+/)) {return "0"+amount; }
  else {return amount; }
}

function paramsWithAuthentication(params) {
  if ((typeof params) == 'undefined') {
    return {authenticity_token: window._authenticity_token};
  } else if ((typeof params) == 'string') {
    return "authenticity_token=" + encodeURIComponent(window._authenticity_token) + "&" + params;
  } else if ((typeof params) == 'object') {
    var authenticatedParams = {authenticity_token: window._authenticity_token};
    for (p in params) { authenticatedParams[p] = params[p] };
    return authenticatedParams;
  } else {
    return false;
  }
}

Object.extend(Form, { 
  // Clear search string from a form 
  wipe: function(form){
    if(form.value == 'Search...') { form.value = ''; }
  }
});

Object.extend(Form.Methods, {
  serializeNested: function(form, options) {
    return form.getElements().collect(function(e){ 
			if (e.disabled != true) {
      	return encodeURIComponent(e.name) + '=' + encodeURIComponent($F(e));
			}
    }).join("&");
  }
});
Element.addMethods();


Object.extend(Element, { 
  
  // Deprecated: See prototype.js getElementsByClassName(element, parent)
  getChildrenByClassName: function(element, className) {
    var nodes = element.childNodes;
    var node;
    for(var i = 0; i < nodes.length; i++) {
      if(nodes[i].nodeType == 1) {
        if(Element.hasClassName(nodes[i], className)) {
         return node = nodes[i];
        }
      }
    }
    return false;
  },

  // Traverse up the DOM finding the first parent with the 
  // tagName equal to tagName
  findFirstParentNamed: function(element, tagName) {
    while (element.parentNode && (!element.tagName ||
        (element.tagName.toUpperCase() != tagName.toUpperCase())))
      element = element.parentNode;
    return element;
  },
  
  // Remove the GrandParent of the element that was passed.
  // Use min_size to control the minimum allowed length of the 
  // GrandParents children.  Good for when you want to have atleast 
  // a childnode present.
  removeGrandParent: function(element, min_size) {
    var gParent = element.parentNode.parentNode;
    var ggParent = gParent.parentNode;
    Element.cleanWhitespace(ggParent);
    
    if(min_size && ggParent.childNodes.length <= min_size)
      return;
    else
      ggParent.removeChild(gParent);
  },
  
  // Toggle the visibility of two elements in sync
  // Good for hiding one element in the precense of another
  togglePair: function(element1, element2) {
    Element.toggle(element1);
    Element.toggle(element2);
  }
});


/*-------------------- Extensions for Element.Methods ------------------------------*/
var ElementExtension = {
  cloak: function(element) {
    $(element).setStyle({visibility: 'hidden'});
  },
  
  uncloak: function(element) {
    $(element).setStyle({visibility: 'visible'});
  }
};

Element.addMethods(ElementExtension);


/*-------------------- Effect.Transitions ------------------------------*/

// Quadratic ease-in and ease-out:
Effect.Transitions.slowStart = function(pos) { return (pos * pos); };
Effect.Transitions.slowStop = function(pos) { return ((-pos) * (pos - 2)); };


/* 
Overshooting Transitions 
*/ 
Effect.Transitions.elastic = function(pos) { 
    return -1*Math.pow(4,-8*pos) * Math.sin((pos*6-1)*(2*Math.PI)/2) + 1; 
}; 

Effect.Transitions.whip = function(pos) { 
    var s = 0.5; 
    if ((pos/=0.5) < 1) return 0.5*(pos*pos*(((s*=(1.525))+1)*pos - s)); 
    s = 0.8; //slightly bigger, slower overshoot at the end
    return 0.5*((pos-=2)*pos*(((s*=(1.525))+1)*pos + s) + 2); 
}; 
// SwingFrom (adapted from "BackEaseIn") 
Effect.Transitions.swingFrom = function(pos) { 
    var s = 1.70158; 
    return pos*pos*((s+1)*pos - s); 
}; 
// SwingTo (adapted from "BackEaseOut") 
Effect.Transitions.swingTo = function(pos) { 
    var s = 1.70158; 
    return (pos-=1)*pos*((s+1)*pos + s) + 1; 
};
// End of Robert Penner & Ken Snyder's stuff


/*-------------------- Area Functions ------------------------------*/

var Area = {
    
  // Clone an html element and insert it into a new 
  // position in the DOM
  cloneHTML: function(from, to, position) {
    var from = $(from);
    var to   = $(to);
    clone = from.cloneNode(true);
  
    switch(position.toLowerCase()) {
      case 'bottom': 
        to.appendChild(clone);
        return clone;
      case 'top'   : new Insertion.Top(to, clone);     break;
      case 'before': new Insertion.Before(to, clone);  break;
      case 'after' : new Insertion.After(to, clone);   break;
    }
    
    return clone;
  }
  
};


/*-------------------- Global Ajax Responders ------------------------------*/

// We use this primarily for auto handling of displaying error messages and 
// success text for Ajax request
Ajax.Responders.register({
  // Show progress indicator and hide 
  // all other notices 
  onLoading: function() {
    if($('flash-errors') != null) { Element.hide('flash-errors'); }
    if($('flash-notice') != null) { Element.hide('flash-notice'); }
  }
    
});

/*-------------------- Messenger Functions ------------------------------*/
// Messenger is used to manage error messages and notices
//
var Messenger = {
  autohide_error: null,
  autohide_notice: null,
  // When given an error message, wrap it in a list 
  // and show it on the screen.  This message will auto-hide 
  // after a specified amount of miliseconds
  error: function(message) {
    $('flasherrors').innerHTML = "<li>" + message + "</li>";
    new Effect.Appear('flasherrors', {duration: 0.3});
    
    if (this.autohide_error != null) {clearTimeout(this.autohide_error);}
    this.autohide_error = setTimeout(Messenger.fadeError.bind(this), 5000);
  },

  // Notice-level messages.  See Messenger.error for full details.
  notice: function(message) {
    $('flashnotice').innerHTML = "<li>" + message + "</li>";
    new Effect.Appear('flashnotice', {duration: 0.3});

    if (this.autohide_notice != null) {clearTimeout(this.autohide_notice);}
    this.autohide_notice = setTimeout(Messenger.fadeNotice.bind(this), 5000);
  },
  
  // Responsible for fading notices level messages in the dom    
  fadeNotice: function() {
    new Effect.Fade('flashnotice', {duration: 0.3});
    this.autohide_notice = null;
  },
  
  // Responsible for fading error messages in the DOM
  fadeError: function() {
    new Effect.Fade('flasherrors', {duration: 0.3});
    this.autohide_error = null;
  }
};

/*-------------------- Feedback Functions ------------------------------*/

var Dialog = Class.create();
Dialog.instances = [];
Dialog.close = function() {
  for (var i=0; i < this.instances.length; i++) {  this.instances[i].close();  };
  this.instances.clear();
};

Dialog.prototype = {
  
  initialize: function(name, url, options) {
    this.content = $( options['content_div'] || "dialog-content");
    this.overlay = $( options['overlay_div'] || "dialog-overlay");
    this.overlay.onclick = function(){ Dialog.close(); return false; };
    this.name = name;
    new Display.appear(this.overlay, {duration: 0.3, to: 0.40});            
    new Ajax.Updater(this.content, url, {evalScripts:true, onComplete: this.onAppear.bind(this), method: options['method'] || "post", parameters: paramsWithAuthentication() } );        
    
    this.shouldAppear = true;
    Dialog.instances.push(this);
  },
  
  onAppear: function() {
    if (this.shouldAppear) {
      this.content.addClassName(this.name);
      this.content.show();    

      if(Prototype.Browser.IE) {
        this.content.up().scrollTo();
      }    
        
      var x = document.viewport.getWidth()  - this.content.offsetLeft*2;
      var y = document.viewport.getHeight() - this.content.offsetTop*3;

      this.content.setStyle({width: x, height: y});
    }
  },
  
  close: function() {
    this.shouldAppear = false;
    this.content.hide();
    this.content.removeClassName(this.name);
    new Effect.Fade(this.overlay, {duration: 0.3});
  }
};

/*-------------------- Product Administration Functions ------------------------------*/

var Product = {
  product_id: null,
  
  // Create a div with the class name featured and 
  // position it over the featured image (firstChild) of the 
  // given parent.
  markFeaturedImage: function()  {
    if (!$('image_list')) { return; }
    var star = Builder.node('div', {className: 'featured'});
    var list = $('image_list');
    var current = list.firstChild;
    if(!current) return;
    Element.cleanWhitespace(list);
    images = $A(list.childNodes);
    images.each(function(image) {
      if(image.select('.featured').length != 0)
        image.removeChild(image.select('.featured')[0]);
    });
        
    current.appendChild(star);
  },
  
  makeImagesSortable: function() {
    if (!$('image_list')) { return; }
    Sortable.create('image_list', { 
      constraint:false, 
      handle:'image-drag', 
      onUpdate: function() {
        new Ajax.Request("/admin/products/"+Product.product_id+"/images/reorder", {
          method: 'POST', parameters: paramsWithAuthentication(Sortable.serialize('image_list'))
        });       
      }, 
      overlap:'horizontal'
    });
  },
  
  removeImage: function(mediafile)  {
    mediafile = $(mediafile);
    if (mediafile) {
      Element.remove(mediafile);
    }
    
    setTimeout("Product.markFeaturedImage();", 1000);
  },
  
  toggleType: function() {
    var field = $('type');
    var enable = field.options[field.selectedIndex].value == 'create_new';

    Product.show('create_type', enable);
  },

  toggleVendor: function() {
    var field = $('vendor');
    var enable = field.options[field.selectedIndex].value == 'create_new';

    Product.show('create_vendor', enable);
  },

  show: function(item, visible) {
    if(visible) {
      Element.show(item);
    } else {
      Element.hide(item);
    }    
  },
  
  toggleSortable: function(productID) {
    $$('.sortable-related').each(function(handle){
       Element.toggle(handle);
     });
     Sortable.create('variant_list',
       { handle:'drag-handle', 
         onUpdate:function(){new Ajax.Request('/admin/products/'+productID+'/variants/reorder', { parameters: paramsWithAuthentication(Sortable.serialize('variant_list'))});},
         constraint: 'vertical'});


    Element.togglePair('apply-order', 'reorder-lbl');    
  },
    
  linkCollection: function(collection_id, linkage) {
    var highlight = function(){ new Effect.Highlight('collection-'+collection_id, {endcolor: '#F4F9FB'}); };
    
    if(linkage) {
      new Ajax.Request('/admin/collects', {method: 'POST', parameters: paramsWithAuthentication('context=none&collect[product_id]='+this.product_id+'&collect[collection_id]='+collection_id), onSuccess: highlight} );
    }
    else {    
      new Ajax.Request('/admin/collects/'+this.product_id+'-'+collection_id, {parameters: paramsWithAuthentication('context=none'), method: 'DELETE', onSuccess: highlight});
    }    
  },
  
  updateFulFillmentOptions: function(variantID) {
		var inventorySelect = $('fulfillment-select-' + variantID);
		
		if (inventorySelect == null) {
			return;
		}
		
    if ( inventorySelect.value == 'shipwire') {
			// Insert the Shipwire option if it isn't there yet
			this.addInventoryService('shipwire', variantID);
      this.updateTrackingOptions(variantID);
      $('shipwire-info-'+variantID).show();
    } else {
			this.removeInventoryService('shipwire', variantID);
			
      $('shipwire-info-' + variantID).hide();
			$('shipwire-inventory-' + variantID).hide();
      
      if ($('inventory-select-'+variantID).value == 'shipwire') {
        $('inventory-select-'+variantID).value = '';
        this.updateTrackingOptions(variantID);
      }
    }
  },

	addInventoryService: function(name, variantID) {
		var options = $('inventory-select-' + variantID).options;
		
		if (!this.hasInventoryService(name, variantID)){
		  options.add(new Option(name.capitalize() + " tracks this variant's stock level", name), 2);
		}
	},
	
	hasInventoryService: function(name, variantID) {
	  var options = $('inventory-select-' + variantID).options;
	  return $A(options).detect(function(e) { return e.value == name; });
	},

	removeInventoryService: function(name, variantID) {
		var options = $A($('inventory-select-' + variantID).options);
		options.each(function(option) {
			if (option.value == name) {
				Element.remove(option);
      }
    });
	},	

  updateTrackingOptions: function(variantID) {
    this.hideAllTrackingOptions(variantID);
    this.showTrackingOptions(variantID);
  },
  
  hideAllTrackingOptions: function(variantID) {
    $('inventory-controls-'+variantID).select('.inventory-option').each( function(control) {Element.hide(control); } );
    $('inventory-policy-'+variantID).hide();
  },
  
  showTrackingOptions: function(variantID) {
    if($('inventory-select-'+variantID).value != '') {
      $('inventory-policy-'+variantID).show();
      $($('inventory-select-'+variantID).value+"-inventory-"+variantID).show();
    }
  },
  
  updateListTools: function(elem) {
    lastVariants = elem.select('li.last-variant');
    container_height = 40;
    
    lastVariants.each(function(variant) {

      if(variant.offsetTop > container_height) {        
        variant.up().up().select('div.expand-collapse-info')[0].show();
      } else {
        variant.up().up().select('div.expand-collapse-info')[0].hide();
      }
    });
  },
  
  expandList: function(productID) {
    $('variant-list-'+productID).setStyle('overflow:visible'); 
    $('variant-list-'+productID).setStyle('height:auto');
    $('expand-'+productID).hide(); 
    $('collapse-'+productID).show();
  },
  
  collapseList: function(productID) {
    $('variant-list-'+productID).setStyle('overflow:hidden');
    $('variant-list-'+productID).setStyle('height:50px');
    $('collapse-'+productID).hide();
    $('expand-'+productID).show(); 
  }

};

ProductList = Class.create();
ProductList.prototype = {

	initialize: function(container, controls) {
		this.container        = $(container);
    this.controls         = $(controls);
    this.productSelectors = this.container.select('input[type="checkbox"].selector');
    this.updateList();
    this.markSelectedRows();
    this.outputProductCount();
    this.resetDropDown();
	},
	
	updateList: function() {
	  this.findActiveProducts();
    this.markSelectedRows();
    this.toggleControls();	  
	},
	
	findActiveProducts: function() {
    var active = [];

		this.productSelectors.each(function(elem) {
		  if (elem.checked) {
		    active.push(elem.value);
	    }
		});		
		this.activeProducts = active;
    this.outputProductCount();	  
	},

  toggleControls: function() {
    if (this.activeProducts.length > 0) {    
      this.controls.show();
    } else {
      this.controls.hide();
      this.container.select('input[type="checkbox"]')[0].checked = "";
    }
  },

	toggleAllProducts: function(tableElement, toggleElement) {
		if (toggleElement.checked) {
			this.selectAllProducts(tableElement);
		} else {
			this.deselectAllProducts(tableElement);
		}
	},

  selectAllProducts: function(tableElement) {
    tableElement.select('input[type="checkbox"].selector').each(function(elem){
      if (elem.checked == '') { elem.simulate('click'); }
    });
    this.updateList();
  },

  deselectAllProducts: function(tableElement) {
    tableElement.select('input[type="checkbox"].selector').each(function(elem){
      if (!elem.checked == '') { elem.simulate('click'); }
    });
    this.updateList();
  },

  getParamFromURL: function(name) {
    name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
     var regexS = "[\\?&]"+name+"=([^&#]*)";
     var regex = new RegExp( regexS );
     var results = regex.exec( window.location.href );
     if( results == null ) {
       return "";
     } else {
       return results[1];
     }
  },
  
  toParam: function(name) {
    if(eval("this."+name).length > 0) {
      return name+'='+eval("this."+name)+'&';
    } else {
      return '';
    }
  },
  
  markSelectedRows: function() {
    this.container.select('tr').each(function(row) {
      row.removeClassName('active');
    });
    
    this.activeProducts.each(function(id) {
      $('row-'+id).addClassName('active');
    });
  },
  
  resetDropDown: function() {
    $('product-select').selectedIndex = 0;
  },
  
  outputProductCount: function() {
    $('product-count').innerHTML = this.activeProducts.length+" product".pluralize(this.activeProducts.length, ' products')+" selected";
  },
  
  submitWithAjax: function() {
    new Ajax.Request('/admin/products/set', {asynchronous:true, evalScripts:true, parameters:Form.serialize($('batch-form'))});
  },
  
  submitForm: function(select) {
    if(select.value != ''){ 
      if(select.value == 'destroy') { 
        if(confirm('Are you sure you want to delete the selected products?')) { 
          $('batch-form').submit(); 
        } else {
          this.resetDropDown();
        }
      } else if(select.value.match('http://')) {
        window.location = select.value;
      } else {
        $('batch-form').submit(); 
      }
    }
  }

};

// 
var ProductVariantList = Class.create(ProductList,{

	initialize: function(container, controls) {
		this.container        = $(container);
    this.controls         = $(controls);
    this.productSelectors = this.container.select('input[type="checkbox"].selector');
    this.updateList();
    this.markSelectedRows();
    this.outputProductCount();
    this.resetDropDown();
	},
		
	updateList: function() {
		this.resetDropDown();
	  this.findActiveProducts();
    this.markSelectedRows();
    this.toggleControls();
		// enable duplicate options (if applicable)
		this.enableDuplicateOptions();
	},
	
	// <option id="dup-property-1"></option>
	enableDuplicateOptions: function() {
		// enable property select option where # of different property values == 1
		[1,2,3].each(function(pos_id){
			var values = [];
			this.activeProducts.each(function(el){
				$('row-'+el).select(".option-"+pos_id).each(function(node){ 
				  values.push(node.down('label').innerHTML);
				});
				var dom_id = "dup-option-"+pos_id;
				if (values.uniq().size() == 1) {
					if ($(dom_id))
						$(dom_id).disabled = false;
				} else {
					if ($(dom_id))
						$(dom_id).disabled = true;
				}
			});
		}.bind(this));
	},
	
	buildVariantList: function() {
		this.activeProducts.each(function(el){
			var input = "<input class='variant_ids' type='hidden' name='variants[]' value='"+el+"' />";
			$('batch-form').insert(input);
		});
	},
	
	// remove all input fields for variant_ids
	clearVariantList: function() {
		$('batch-form').select('input.variant_ids').each(function(el){el.remove()});
	},

  resetDropDown: function() {
    $('product-select').selectedIndex = 0;
		$('new-value').hide();
  },
  
	// select elements based on the class of table row
	selectByOption: function(tableElement, pos_id, value) {
		this.deselectAllProducts(tableElement);
		tableElement.select('tr.inventory-row td.option-'+pos_id).each(function(el){
		  var label = el.down('label');
			if (label.innerHTML == value) {
				el.ancestors().first().select('input[type="checkbox"]').each(function(elem){
					elem.checked = 'checked';
				});
			}
		});
		this.updateList();
	},
  
	// update whether to display 'new-value' div
	updateForm: function(select) {
	  if (select.value == "destroy") {
      this.submitForm(select);
	  } else if (["price", "quantity", "duplicate-1", "duplicate-2", "duplicate-3"].include(select.value)) {
	    $('new-value').show();
	    $('new-value').down().focus();
	  } else {
	    $('new-value').hide();
	  }
	},
	
	submitForm: function(select) {
		// build select items array
		this.clearVariantList();
		this.buildVariantList();
		if (select.value != '') {
			if (select.value == 'destroy') {
				if (confirm('Are you sure you want to remove the selected items?')) {
					$('batch-form').submit();
				} else {
					this.resetDropDown();	
				}
			} else {
				$('batch-form').submit();
			}
		}
	}

});




var OrderList = Class.create(ProductList, {
	initialize: function(container, controls) {
		this.container        = $(container);
    this.controls         = $(controls);
    this.productSelectors = this.container.select('input[type="checkbox"].selector');
    this.updateList();
    this.markSelectedRows();
    this.outputProductCount();
    this.resetDropDown();
	},
	
  resetDropDown: function() {
    $('order-select').selectedIndex = 0;
  },
	
	outputProductCount: function() {
    $('order-count').innerHTML = this.activeProducts.length+" order".pluralize(this.activeProducts.length, ' orders')+" selected";

	},
  submitForm: function(select) {
    if(select.value != ''){ 
      if(select.value == 'ship') { 
        if(confirm('This will send a shipping notification email for all items in the order to each customer. Are you sure you wish to ship and confirm all selected orders?')) { 
          $('batch-form').submit(); 
        } else {
          this.resetDropDown();
        }
 /*
     } else if(select.value == 'close') {
        if(confirm("Closing abandoned orders will delete them. Are you sure you wish to close all selected orders?")) {
          $('batch-form').submit();
        } else {
          this.resetDropDown();
        }
*/
      } else {
        $('batch-form').submit();  
      }
    }
  }
	
});


var UpdateableSelectBox = Class.create({
	initialize: function(id, targetField, label, options) {
		if (!$(id)) { return } //fail if doesn't exist
		this.select = $(id);
    this.targetField = $(targetField);
		this.label = label || 'Create new...';  

    if(options) {
		  this.container = $(options.container);
		} else {
		  this.container = this.targetField;
		}

    if(this.select.length == 0) {
      this.select.hide();
      this.targetField.show();
    } else {
  		this.insertRequiredOptions();
      this.selectOption(this.targetField.value);				
  		this.select.observe('change', this.onSelectedOptionChanged.bindAsEventListener(this));
	  }
	},

	insertRequiredOptions: function() {
    if(Prototype.Browser.IE) {
  		this.select.options.add(new Option("--------", ""));
  		this.select.options.add(new Option(this.label, "create_new"));
    } else {
		  this.select.insert(new Option("--------", ""));
      this.select.insert(new Option(this.label, "create_new"));
    }
	},

  currentOption: function(select) {
    if(Prototype.Browser.IE) {
      return this.select.options[this.select.selectedIndex].text;
    } else {
      return this.select.value;
    }    
  },

	onSelectedOptionChanged: function(event) {
	  // need this instead of this.select.value for IE6 compatibility!
    var selected = this.select.options[this.select.selectedIndex].value;

		if (selected == 'create_new') {
      // Clear and show target textfield
      this.targetField.value = "";
      this.container.show();
		} else {
		  // assign selected option to target textfield
      this.targetField.value = this.currentOption(this.select);
      this.container.hide();
		}
	},

	optionExists: function(value) {
		return $A(this.select.options).detect( function(option){ return option.value == value; });
	},

	selectOption: function(value) {
    var found = false;

	  if (value == null || value.blank()){
	   	this.targetField.value = this.currentOption(this.select);
			return;
		}
    
		$A(this.select.options).each( function(option, index){
		  if (option.value == value) {
  	 		this.select.selectedIndex = index;
				this.targetField.value = value;
        found = true;
				return;
			}
		}.bind(this));
		
		// if value cant be found in select, default to 'create_new'
		if(!found) {
	    this.select.selectedIndex = this.select.length - 1;
		  this.container.show();
	  }
	}
});

var OptionSelectBox = Class.create(UpdateableSelectBox, {
  initialize: function($super, id, targetField, label, defaultField, options) {
    $super(id, targetField, label, options);
    this.defaultField = $(defaultField);
    this.updateDefaultField();
  },
  
  onSelectedOptionChanged: function($super, event) {
    $super(event);
    var selected = this.select.options[this.select.selectedIndex].value;
		if (selected == 'create_new') {
      this.updateDefaultField();
      this.targetField.select();
    } else {
      this.updateDefaultField();
    }
  },
  
  updateDefaultField: function() {
    if (this.targetField) {
      this.defaultField.value = "Default "+this.targetField.value;
      this.defaultField.select();
    }
  }
});

var FileAttachments = Class.create({
  itemElement: new Template('<img src="/images/admin/icons/trash.gif" class="delete fr" /><img src="/images/admin/icons/attachment.png" /> #{filename}'),
  
  initialize: function(element) {
    this.files = new $H();
    this.container = $(element);
    this.fileDialogs = this.container.down();
    this.fileContainer = $('file-input');
    this.fileContainer.down().id = null;
    this.pendingFiles = $('pending-files');
    this.attachments = $('attachments');
    this.observeFileChange();
    this.initializePendingFiles();
  },
  
  initializePendingFiles: function() {
    var attachments = this.attachments.select('li.tempfile');
    var pendingFiles = this.pendingFiles.select('input');
    //attachments.each(function(e){ e.id = null; });
    pendingFiles.each(function(e){ e.id = null; });

    attachments.each(function(item, index){
      this.files.set(item.identify(), pendingFiles[index].identify());
      this.observeRemoveClick(item);
    }.bind(this));
  },
  
  observeFileChange: function() {
    this.fileContainer.down().observe('change', this.onFileContainerChange.bindAsEventListener(this));
  },
  
  observeRemoveClick: function(item) {
    item.observe('click', this.onRemoveButtonClick.bindAsEventListener(this));
  },
  
  onFileContainerChange: function(event) {
    element = event.element();
    this.files.set(this.addAttachmentItem(element), this.addFileDialog(element));
  },
  
  addFileDialog: function(element) {
    var fileContainer = element.up();
    var inputFieldHTML = fileContainer.innerHTML;
    this.fileDialogs.appendChild(element);
    fileContainer.innerHTML = inputFieldHTML;
    this.observeFileChange();
    return element.identify();
  },
  
  addAttachmentItem: function(element) {
    var li = new Element('li');
    li.addClassName("item");
    li.insert(this.itemElement.evaluate({ filename: element.value.split(/(\/|\\)/).last() }));
    $('attachments').appendChild(li);
    $('no-product-images-msg').hide();
    this.observeRemoveClick(li.down('img.delete'));
    return li.identify();
  },
  
  onRemoveButtonClick: function(event) {
    var element = event.element();
    var li = element.up();
    var fileDialogID = this.files.unset(li.identify());
    li.remove();
    $(fileDialogID).remove();
    
    if(this.files.keys().length == 0) { $("no-product-images-msg").show(); }
  }
});

/*-------------------- Collection Administration Functions ------------------------------*/

var Collection = {
  	
	markFeaturedCollection: function(product_id, label_id)	{
		if ($('featured_'+product_id).innerHTML == 'true') {
			$('feature_image_'+product_id).src='/images/admin/icons/empty_star.png'; 
			$('featured_'+product_id).innerHTML = 'false';
		}
		else {
			$('feature_image_'+product_id).src='/images/admin/icons/star.png'; 
			$('featured_'+product_id).innerHTML = 'true';
		}
		
		new Ajax.Request('/admin/labels/mark_featured/'+label_id, {parameters: paramsWithAuthentication('product='+product_id+'&value='+$('featured_'+product_id).innerHTML) });
	},
	
	createSortable: function(label_id, labelname)	{
		Sortable.create('assoc',{dropOnEmpty: true, containment: ['searchproducts','assoc'],
			onUpdate:function(){new Ajax.Request("/admin/labels/refresh_products/"+label_id,{evalScripts:true, parameters: paramsWithAuthentication(Sortable.serialize('assoc'))});}});
	
		
    Droppables.add('assoc', {
       accept: 'alt_products',
       onDrop: function(element) { 
           new Ajax.Updater('assoc', '/admin/labels/add_product_to_customlabel/' + label_id, {
              asynchronous:true, 
              evalScripts:true, 
              parameters: paramsWithAuthentication('product='+ element.id),
              insertion: Insertion.Top, 
              onComplete:function(request) {
                new Effect.Highlight('assoc_'+element.id);
                Collection.createSortable(label_id,labelname); }
              }); 
              return false;
            }
          });

  }
};

/*-------------------- Shipping Preferences Administration Functions ------------------------------*/


var CarrierShippingRateProvider = {
  
  openEditArea: function(providerID) {
    
    var editForm = $("edit_carrier_shipping_rate_provider_" + providerID);
    var editLink = $("edit_link_carrier_shipping_rate_provider_" + providerID);
    var editCell = editForm.up();
    var upperRow = editCell.up().previous('tr');
    editCell.show();
    upperRow.addClassName("edit-shipping-provider-active");
    new Effect.Parallel([
        new Effect.Morph(editCell, {style: {background: "#FFFBE5", paddingLeft: "6px"}}),
        new Effect.Morph(upperRow, {style: {background: "#FFFBE5"}}),
        new Effect.BlindDown(editForm)
      ],
      {
        afterFinish: (function(obj) {
          editLink.hide();
        }),
        duration: 0.7, transition: Effect.Transitions.slowStop
      });

  },
  
  closeEditArea: function(providerID) {
    var editForm = $("edit_carrier_shipping_rate_provider_" + providerID);
    var editLink = $("edit_link_carrier_shipping_rate_provider_" + providerID);
    var editCell = editForm.up();
    var upperRow = editCell.up().previous('tr');
    new Effect.Parallel([
        new Effect.Morph(editCell, {style: {background: "#FFFFFF", paddingLeft: "0px"}}),
        new Effect.Morph(upperRow, {style: {background: "#FFFFFF"}}),
        new Effect.BlindUp(editForm)
      ],
      {
        afterFinish: (function(obj) {
          upperRow.removeClassName("edit-shipping-provider-active");
          editCell.hide();
          editLink.show();
        }),
        duration: 0.7,
        transition: Effect.Transitions.slowStart
      });
  }
  
};

/*--------------------------------------------------------------------*/

//Display controls the visual appearance of elements on the screen.
//Its primary purpose is to show and hide different sets of elements 
//with different styles and effects.

var Display = {
  
  showWithEffect: function(element) {
    new Effect.Appear(element, {duration: 0.3});
  },

  hideWithEffect: function(element) {
    new Effect.Fade(element, { duration: 0.15});
  },           

  toggleWithEffect: function(element, hide, visibility) {
    if (hide != null) this.hideGroup(hide);
    
    if(visibility != null) {
      if (visibility) { this.showWithEffect(element); } else { this.hideWithEffect(element); }
    } 
    else {      
      if($(element).style.display == 'none') { this.showWithEffect(element);} else { this.hideWithEffect(element); }
    }        
  },            
  
  toggleBlock: function(name) {
    Element.toggle(name + '-view');
    Element.toggle(name + '-edit');
  },
  
  scrollTo: function(element) {
    new Effect.ScrollTo(element);
  },
  
  //Hides a group of elements
  //Expects a string of 1 element ("ele"), or an array of strings(["ele1", "ele2"])
  hideGroup: function(elements) {
    if (elements.constructor == Array) {
      for (var i = 0; i < elements.length; i++) {
        Element.hide(elements[i]);
      }
    } else {
      Element.hide(elements);
    }
  },

  hideChildrenByClassName: function(element, className) {
    var elements = Element.getChildrenByClassName(element, className);
    this.hideGroup(elements);
  },
  
  showContent: function(base_name) {
    Element.hide(base_name + '_label');
    new Effect.Appear($(base_name + '_content'), {duration:0.3});
  },                                                         
  
  hideContent: function(base_name) {
    new Effect.Fade(base_name + '_content', {duration:0.3});
    Element.show(base_name + '_label');
  },

  appear: function(element) {
    var options = Object.extend({
    from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0),
    to:   0.99,
    beforeSetup: function(effect) { 
      Element.setOpacity(effect.element, effect.options.from);
      Element.show(effect.element); }
    }, 
    arguments[1] || {});
    return new Effect.Opacity(element,options);
  }
};


/*--------------------------------------------------------------------*/

Object.extend(Form.Element, {
  
  // Toggle height of a form input where element is the 
  // element that fired the event and target is the input you want 
  // to toggle.
  //
  toggleHeight: function(element, target, options) {
    var options = options || {};
    Element.Class.toggle(target, options['shortClass'] || 'short', options['tallClass'] || 'tall');
		Element.Class.toggle(element, 'less', 'more');
    if(element.innerHTML.toLowerCase() == "more room to type")
      element.innerHTML = "Less room to type";
    else
      element.innerHTML = "More room to type";
  }
});


/*----------------- Array Extensions -------------------------*/

Object.extend(Array.prototype, {
  eachElement: function(iterator) {
    for (var i = 0; i < this.length; i++) {
      if(this[i].nodeType == 3)
        iterator(this[i]);
      }
    }
  });


/*----------------- String Extensions -------------------------*/

Object.extend(String.prototype, {
  pluralize: function(count, plural) {
    if (plural == null)
      plural = this + 's';
    return (count == 1 ? this : plural);
  }
});

/*----------------------TOOLBOX-------------------------------*/
//
ToolBox = Class.create();
ToolBox.current = null;
ToolBox.prototype = {      
  initialize: function(element) {       
    this.toolbox = $(element);
    if(!this.toolbox) return;
    this.timeout = null;
    this.tools = this.findTools();
    
    Event.observe(this.toolbox, 'mouseover', this.onHover.bindAsEventListener(this), true);
    Event.observe(this.toolbox, 'mouseout', this.onBlur.bindAsEventListener(this), true);
    Event.observe(this.tools, 'mouseover', this.onHover.bindAsEventListener(this));
    Event.observe(this.tools, 'mouseout', this.onBlur.bindAsEventListener(this));
  },
  
  show: function() {
    if(this.timeout) { 
      clearTimeout(this.timeout); 
      this.timeout = null;
    }    
    
    if(ToolBox.current) {
      ToolBox.current.hideTools();      
    }
    
    if(this.tools) { 
      Element.show(this.tools); 
      ToolBox.current = this;
    }    
  },

  onHover: function(event) {
    this.show();
  },

  onBlur: function(event) {
    this.considerHidingTools();
  },

  considerHidingTools: function() {
    if(this.timeout) { clearTimeout(this.timeout); }
    this.timeout = setTimeout(this.hideTools.bind(this), 500);
  },

  hideTools: function() {
    clearTimeout(this.timeout);
    this.timeout = null;
    Element.hide(this.tools);          
  },

  findTools: function() { 
    var tools = this.toolbox.select('.tools')[0];
    if(!tools) { throw "You called new ToolBox() on an element which has no class=\"tools\" child element"; }
    return tools;
  }
};

Sorting = {
  toggleSortable: function(name, resource, list_id) {
    if (!list_id) { var list_id = ''; }
    if (!resource) { var resource = name; }
    $(name).select('.drag-handle').each ( function(handle) { Element.toggle(handle); });
    Sortable.create($(name), { 
        handle:   'drag-handle', 
        onUpdate: function(){
          new Ajax.Request('/admin/' + resource + '/reorder/' + list_id, { parameters: paramsWithAuthentication(Sortable.serialize(name)) });
        }
      }
    );
    var suffix = '';
    if (list_id != '') {
      suffix = '-' + list_id;
    }
    Element.togglePair('reorder-list'+ suffix, 'apply-listorder' + suffix);
  }
};


TagList = Class.create();
TagList.prototype = {      
  initialize: function(line, list) {
    this.line = $(line);      
    this.list = $(list);

    var tagNodes = this.allTagNodes();

    Event.observe(this.line, 'keyup', this.onTagLineChange.bindAsEventListener(this));

    tagNodes.each(function(a) {
      Event.observe(a, 'click', this.onTagClick.bindAsEventListener(this));
      a.onclick = function() { return false; };
    }.bind(this));

    this.updateTagLine(this.fetchCurrentTags());
  },

  onTagLineChange: function(event) {
    this.updateActiveTags();  
  },

  allTagNodes: function() {
    if(this.tagNodes == null) { this.tagNodes = $A(this.list.getElementsByTagName('a')); }
    return this.tagNodes;
  },

  onTagClick: function(event) {
    this.toggleTag(Event.element(event).innerHTML.unescapeHTML());
    Event.stop(event);
  },

  toggleTag: function(tag) {
    var tags = this.fetchCurrentTags();

    if(tags.include(tag)) {
      tags = tags.reject(function(elem){ return elem == tag; });
    } 
    else {
      tags.push(tag);
    }

    this.updateTagLine(tags);
  },

  tagWords: function() {
    return this.allTagNodes().collect(function(item) { return item.innerHTML; });
  },

  fetchCurrentTags: function() {
    return $F(this.line).split(',').collect(function(tag) {
      return tag.strip();
    }).reject(function(str){
      return str == '';
    });
  },

  updateTagLine: function(tags) {
    this.line.value = tags.join(", ");
    this.updateActiveTags();
  },

  updateActiveTags: function() {
    var tags = this.fetchCurrentTags();
    this.allTagNodes().each(function(a) {
      if(tags.include(a.innerHTML.unescapeHTML() )) {
        Element.addClassName(a, "active"); 
      }
      else  { 
        Element.removeClassName(a, "active"); 
      }
    });        
  }  
};

var LinkForm = {
  toggleSortable: function(name, list_id) {        
    $(name).select('.drag-handle').each ( function(handle) { Element.toggle(handle); });
    Sortable.create($(name), { 
        handle:   'drag-handle', 
        onUpdate: function(){
          new Ajax.Request('/admin/links/reorder/'+list_id, { parameters: paramsWithAuthentication(Sortable.serialize(name)) });
        }
      }
    );
    
    Element.togglePair('reorder-list-'+ list_id, 'apply-listorder-' + list_id);
  },
  
  toggleTags: function(parent) {
    var input  = $(parent).select('.choose-tags')[0];
    var span   = $(parent).select('.with-tags')[0];
    
    if(span.visible()) {
      span.hide(); 
      input.show();
    } else { 
      span.show(); 
      input.hide();
    }
  }      
};

LinkForm.LinkList = Class.create({
  list: null,
  
  initialize: function(list) {
    this.list = $(list);
    this.list.select('.selector')[0].observe('change', this.showCorrectDetail.bind(this));
    this.showCorrectDetail();
  },
       
  showCorrectDetail: function() {
    var element = this.list.select('.selector')[0];
    
    $$('.details').each(function(e) { Element.hide(e); });
    
    detail_span = this.list.select('.'+$F(element) + '-detail')[0];
    if (detail_span) { Element.show(detail_span); }
  }
  
});

var Order = {
	numberPattern: /\{\{\s*number\s*\}\}/,
	
  showShippingItems: function(element) {
    [ 'unshipped-goods', 'mark-shipped', 'mark-shipped-submit', 'order-note' ].each(Element.toggle); 
    $$('#order .fulfill').invoke('show');
    $$('.summary').invoke('hide');
    $('order-note').hide();
  },
  
  hideShippingItems: function(element) {
    [ 'unshipped-goods', 'mark-shipped', 'mark-shipped-submit' ].each(Element.toggle); 
    $$('#order .fulfill').invoke('hide');
    $$('.summary').invoke('show');
    
    if($('note-body').innerHTML != '') { 
      $('order-note').show();
    }   
  },

	format_number: function(format, number) {
		if(!format.match(this.numberPattern)) { 
			return '#' + number.toString(); 
		} else {
			return format.gsub(this.numberPattern, number.toString());
		}
  }
};

var Dashboard = {

  showVisitDetails: function(count, date)  {
    $('visits-count').innerHTML = count;
    $('visits-date').innerHTML = "visits on "+date;
    $('visits-today').hide();
    $('visits-details').show();
  },
  
  hideVisitDetails: function() {
    $('visits-details').hide();
    $('visits-today').show();
  }
  
};

CountryChoice = Class.create();
CountryChoice.prototype = { 
  
  initialize: function(countrySelect, prefix, pleaseSelect) {
    countrySelect = $(countrySelect);
    this.field   = $(prefix);
    this.select  = $(prefix + "_select");
    this.message = $(prefix + "_message");
    this.label   = $(prefix + "_label");
    this.pleaseSelect   = pleaseSelect;

    this.label.innerHTML = '';
    
    this.onCountryChange(countrySelect, $F(countrySelect));    
    
    new Form.Element.EventObserver(countrySelect, this.onCountryChange.bind(this) );
    new Form.Element.EventObserver(this.select, this.onProvinceChange.bind(this) );    
  },
  
  onProvinceChange: function(select, value) {
    this.field.value = value;
  },
      
  onCountryChange: function(select, value) {
    var country = CountryDB.getCountry(value);
    
    if(country == null) {return; }
    
    this.label.innerHTML = country.zone_label;    
    this.select.hide();
    this.field.hide();
    this.message.hide();
    
    switch(country.zone_style) {
    case 'select': 
      this.select.innerHTML = ''; 
      
      if(this.pleaseSelect == true) {
        var startOption = document.createElement('option');
        startOption.innerHTML = "&mdash; Please Select &mdash;";
        this.select.appendChild(startOption);
      }

      for(var i=0; i < country.zones.length; i++ ) {
        var zone = country.zones[i];
        var option = document.createElement('option');
        option.appendChild(document.createTextNode(zone['name']));
        this.select.appendChild(option);
        if(zone['name'] == this.field.value) { 
          if (this.pleaseSelect == true) {this.select.selectedIndex = i+1;}
          else {this.select.selectedIndex = i;}
        }
      }          
      this.select.show();  
      break;
    case 'ask':
      this.field.show();
      break;
    case 'hidden':
      this.message.show();        
      this.message.innerHTML = 'not required...';
      this.field.value = '';
    }
  }
}; 

var Domains = {
  addLine: function() {
    var id = 'domain_' + new Date().getTime();
    new Insertion.Bottom('domain-inputs', this.template(id));
  },
  
  removeLine: function(id) {
    Element.remove(id);
  },
  
  template: function(id) {
    return '' + 
    '<li id="' + id + '" class="st">' + 
    'http:// <input type="text" name="domain[host][]" size="32" /> ' + 
    '<span class="smart-tools">' + 
      '<a href="#" onclick="Domains.addLine(); return false;"><img alt="Add" src="/images/admin/icons/add.gif" /></a>' + 
      '<a class="del" href="#" onclick="Domains.removeLine(\'' + id + '\'); return false;" title="Remove this"><img alt="Delete" src="/images/admin/icons/delete.gif" /></a>' + 
    '</span>' +
    '</li>';
  }
};

GatewayForm = Class.create();
GatewayForm.prototype = {
  initialize: function(prefix, active_id) {
    this.prefix = prefix;
    this.activated_id = active_id;
    this.select = $(this.prefix + '-gateway-id');
				
		if (this.select == null) return;

		Event.observe(this.select, 'change', this.gatewayChange.bind(this));
		this.gatewayChange();	
  },
  
  gatewayChange: function() {
    $$('.' + this.prefix + '-properties').invoke('hide');
    if(this.select.value != "") {
      $(this.selectedName()).show();
    }
  },
  
  selectedName: function() {
    return 'account_payment_provider_' + this.select.value;
  }
};

OrderProcessingForm = Class.create();
OrderProcessingForm.prototype = {
  initialize: function(forms, ids) {
    this.forms = forms;
    this.dropdowns = forms.select(function(f){ return f.select != null; }).pluck('select');
    this.supportedGateways = ids;
    this.orderProcessing = $('order-processing');
    
    this.dropdowns.each(function(s){
      Event.observe(s, 'change', this.gatewayChange.bind(this));
    }.bind(this));
    
    this.gatewayChange();
  },
  
  gatewayChange: function() {
    if (this.anyWithSupportSelected()) {
      this.orderProcessing.show();
    } else {
      this.orderProcessing.hide();
    }
  },
  
  anyWithSupportSelected: function() {
    return(this.dropdowns.any(function(s){ return this.supportedGateways.include(parseInt(s.value)); }.bind(this)) ||
      this.forms.any(function(f){ return this.supportedGateways.include(f.activated_id); }.bind(this)));
  }
};

CustomPaymentMethodForm = Class.create();
CustomPaymentMethodForm.prototype = {
  initialize: function(configured) {
    this.configured = configured;
    this.select = $("select_custom_payment_method");
    this.form = $("account_manual_payment_gateway");
    this.name = $("name_manual_payment_gateway");
    
    this.select.observe('change', this.selectChange.bind(this));
    this.selectChange();
    this.removeSelected();
  },
  
  selectChange: function() {
    if (this.select.value == "") {
      this.form.hide();
    } else {
      this.form.show();
      if (this.select.value == "custom"){
        this.name.value = "Enter custom payment method name";
        this.name.activate();
      } else {
        this.name.value = this.select.value;
      }
    }
  },
  
  removeSelected: function() {
    var options = $A(this.select.options);
    this.configured.each(function(value) {
      options.each(function(option) {
        if (option.value == value) {
   			  // Can't call option.remove() due to IE7 problem
   			  Element.remove(option);
        }
      }); 
    });
  }
};

var Coupon = {
  generate: function() {
    var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var string = '';
    for (var i=0; i<8; i++) {
    	var rnum = Math.floor(Math.random() * chars.length);
    	string += chars.substring(rnum,rnum+1);
    }
    return 'SHOPIFY'+ string;
  }
};

var TextArea = Class.create();
TextArea.prototype = {
  initialize: function(elem) {
    this.elem = $(elem);
  },
  
  resizeToFit: function(elem, offsetX, offsetY) {    
    var d = $(elem).getDimensions();
    this.elem.setStyle({width: d.width - offsetX + 'px', height: d.height - offsetY + 'px' });      
    return this.elem;
  }  
};


var ResizingTextArea = Class.create();
ResizingTextArea.prototype = {
  minSpace: 1,
  increment: 3,
  maxSpace: 30,
  
  initialize: function(field)
  {
      resizeNeeded = this.resizeNeeded.bindAsEventListener(this);
      Event.observe(field, "click", resizeNeeded);
      Event.observe(field, "keyup", resizeNeeded);
      this.resize(field);
  },
  
  totalTextLength: function(field) {
    var lines = field.value.split('\n');
    var rows  = lines.length;

    for (var i = 0; i < lines.length; i++)
    {
        var line = lines[i];
        if (line.length >= field.cols) {
          rows += Math.floor(line.length / field.cols);
        }        
    }    
    return rows;
  },
  
  resize: function(field) {
    var field = $(field);
    var textLen = this.totalTextLength(field);
    
    if(field.rows < this.maxSpace && field.rows - this.minSpace < textLen) {
      field.rows = textLen + this.increment;
    }
  },

  resizeNeeded: function(event)
  {
    this.resize(Event.element(event));
  }
  
};

var ShopifyImage = {
  
  upload: function() {
  	$('form').style.display = 'none';
    $('uploading').style.display = 'block';  	
  	document.iform.submit();
  },
  
  addImageLink: function(textarea, img_link) {
    textarea.focus();
    if(textarea.createTextRange) {
      document.selection.createRange().text += img_link;
    } else if(textarea.setSelectionRange) {
      var len = textarea.selectionEnd;
      textarea.value = textarea.value.substr(0, len)
      + img_link + textarea.value.substr( len );
      textarea.setSelectionRange(len+img_link.length,len+img_link.length);
    } else { textarea.value += img_link; }
  },
  
  select: function(file, link_url) {
    var textareas = $$('.image-target');
    if(textareas != []) {
      
      if (link_url != "") {
        textareas.each(function(textarea) { ShopifyImage.addImageLink(textarea, "\n<a href='"+link_url+"'><img src='"+file+"' alt='' /></a>"); });  
      } else {
        textareas.each(function(textarea) { ShopifyImage.addImageLink(textarea, "\n<img src='"+file+"' alt='' />"); });        
      }
      
      this.hideRecent();
    }
    return false;
  },
  
  showRecent: function() {  
    $('files').setStyle({
      width: "440px", 
      height: "240px",
      overflow: "auto",
      position: "absolute"
    });
    
    $('show-recent-link').hide();
    $('hide-recent-link').show();
  },
  
  fileUploaded: function(basename, thumb_url, path_url, link_url) { 
    var new_li    = new Element('li', {className: 'fl c asset'});
    var new_div   = new Element('div', {className: 'asset-image'});
    var new_img   = new Element('img', {src: thumb_url});
    var new_span  = new Element('span', {className: 'note'});
    var new_link  = new Element('a', {href: '#', onclick: 'ShopifyImage.select(\''+path_url+'\', \''+link_url+'\');return false;'});
    var new_link2 = new Element('a', {href: '#', onclick: 'ShopifyImage.select(\''+path_url+'\', \''+link_url+'\');return false;'});
    
  	new_link.innerHTML = basename.truncate(12);

    new_link2.appendChild(new_img);
    new_span.appendChild(new_link);
    new_div.appendChild(new_link2);
  	new_li.appendChild(new_div);
  	new_li.appendChild(new_span);

    $('files-list').insert({ top: new_li });    
    new Effect.Highlight(new_li);      
    
    this.select(path_url, link_url);
  },
  
  hideRecent: function() {
    if($('files')) {
      $('files').setStyle({
        height: "",
        width: 'auto',
        overflow: "hidden"
      });

      $('show-recent-link').show();
      $('hide-recent-link').hide();
    }
  }
};
  
  
var Asset = {
  
  showImageDialog: function(element) {
    $('add-image-link').hide();
    new Effect.BlindDown('add-image-dialog', { duration: 0.2 });
    if (!$('upload-dialog')) {
      new Ajax.Updater(element, '/admin/files/', {evalScripts:true, method: 'GET'} );
    }
  }, 

  hideImageDialog: function() {
    new Effect.BlindUp('add-image-dialog', { duration: 0.2 });
    $('add-image-link').show();
  }
};



var VariableSelectBox = Class.create({
	initialize: function(id, replaceable_option, options) {
		this.select = $(id);
		this.replaceable_option = replaceable_option;
		this.options = options;
		
		this.select.observe('change', this.onSelectedOptionChanged.bindAsEventListener(this));
	},
		
	onSelectedOptionChanged: function(event) {
		if (this.select.value == this.replaceable_option) {
			var name = prompt(this.options['label'] || "Enter new value:", this.options['default'] || "");	
			
			if (name == null || name.blank()){
				return;
			}
		
			if ( !this.optionExists(name) ) {
				this.insertOption(name);
			}
			
			this.selectOption(name);
		}
	},
	
	optionExists: function(value) {
		return $A(this.select.options).detect( function(option){ return option.value == value; });
	},
	
	selectOption: function(value) {	
		$A(this.select.options).each( function(option, index){
			if (option.value == value) {
				this.select.selectedIndex = index;
				return;
			}
		}.bind(this));
	},
	
	insertOption: function(value) {
  	this.select.options.add(new Option(value, value), this.select.options.length);
	}	
});

function promptDuplicate(subject_type, current_name) {
  var title = prompt(("Enter a title for your new " + subject_type + ":"),current_name);
  if (title != null && title != "") {
  	$('new_' + subject_type + '_title').value = title;
  	$('new_' + subject_type).submit();
  }
}

//----------------------------------------------------------------------------------------------
// Proxies
//----------------------------------------------------------------------------------------------
// var ShopProxyFolder = Class.create({
//   initialize: function(id) {
//     this.id = id;
//    $('shop-proxy-folder-' + id).observe('change', this.submit.bindAsEventListener(this));
//    $('edit-shop-proxy-folder-' + id).hide();
//     $('shop-proxy-folder-' + id).setStyle({display: 'inline'});
//     $('shop-proxy-folder-' + id).select();
//  },
//    
//  submit: function() {
//    new Ajax.Request('shop_proxies/' + this.id, {
//      method: 'put', 
//      parameters: 'folder=' + ($F('shop-proxy-folder-' + this.id))
//    });
//  }
// });

//----------------------------------------------------------------------------------------------
// Options
//----------------------------------------------------------------------------------------------
var Options = {
  row :         "new-option-",
  option_name:   "option-name-",
  option_value:  "option-value-",
  add_option_bt: "add-option-bt",
  options:       [],
  count:        0,        // number of existing options
  deleteableOptions: [],  // existing options to delete
  suggestedOptions:  ["Color", "Size", "Material", "Style"],
  
  update: function(options) {
    this.options = options;
    this.count = this.options.length;
    this.deleteableOptions = [];
    // hide trash link if only one option left
    if (this.count == 1) {
      $$('#product-properties .delete-option-link').each(function(e){
        e.hide();
      });
    };
  },
  
  showWarning: function(id) {
    $('option-'+id+'-delete').show();
    // hide trash 
    $('option-'+id+'-trash').hide();
  },
  
  // mark for deletion
  deleteExistingOption: function(id){
    // there's only 1 option left, alert message and return
    if ((this.count - this.deleteableOptions.length) == 1) {
      alert("This option cannot be deleted");
      return;
    }
    
    // disable and hide input fields
    $('option-'+id+'-id').disable();
    $('option-'+id+'-name').disable();
    $('option-'+id+'-name').hide(); 
    
    // show delete msg div
    $('option-'+id+'-delete').show();
    // hide trash 
    $('option-'+id+'-trash').hide();
    // hide option value
    $('option-'+id+'-value').hide();
    
    // add to deletables
    this.deleteableOptions.push(id);
  },
  
  // undo delete existing option
  undoDeleteExistingOption: function(id){
    // enable and show input fields
    $('option-'+id+'-id').enable();
    $('option-'+id+'-name').enable();
    $('option-'+id+'-name').show(); 
    
    // hide delete msg div
    $('option-'+id+'-delete').hide();
    // show trash 
    $('option-'+id+'-trash').show();
    // show option value
    $('option-'+id+'-value').show();

    // remove from deletables
    this.deleteableOptions = this.deleteableOptions.without(id);
  },
  
  restoreOptions: function() {
    this.deleteableOptions.each(function(e){
      this.undoDeleteExistingOption(e);
    }.bind(this));
  },
  
  // enable first available option slot
  addOption: function() {
    var el = $$('#product-properties .edit-option').find(function(e) { return (!e.visible()) });
    var index = el.id.split('new-option-').last();
    
    $(this.row+index.toString()).show();
    $(this.option_name+index.toString()).enable();
    $(this.option_value+index.toString()).enable();
    this.updateAddOptionBtn();
    $(this.option_value+index.toString()).select();
  },
  
  // disable last activated option slot
  removeOption: function(index) {
    $((this.row+index).toString()).hide();
    $((this.option_name+index).toString()).disable();
    $((this.option_value+index).toString()).disable();
    this.updateAddOptionBtn();
  },

  updateAddOptionBtn: function() {
    // hide or show add-option-bt
    var hiddenOption = $$('#product-properties .edit-option').any(function(e){
      return !e.visible();
    });      
    hiddenOption ? $(this.add_option_bt).show() : $(this.add_option_bt).hide();
  }
};

var NewOption = {  
  toggle: function() {
    if ($('create-options').checked) {
      $('option-create').show();
      
    } else {
      $('option-create').hide();  
    }
  }
};

//----------------------------------------------------------------------------------------------
// Application Links
//----------------------------------------------------------------------------------------------
ApplicationLinkList = Class.create();
ApplicationLinkList.prototype = {

	initialize: function(container, sidebar, dropdown) {
		this.container        = $(container);
		this.sidebar          = $(sidebar);
		this.dropdown         = $(dropdown);
    this.selectors        = this.container.select('input[type="checkbox"].selector');
    this.addApplicationLinkHandlers();
	},

	addApplicationLinkHandlers: function() {
	  this.selectors.each(function(elem) {
      elem.observe('click', this.onCheck.bindAsEventListener(this));
		}.bind(this));		
	},
	
	onCheck: function(event) {
	  elem = event.element();
	  
	  // update sidebar elements
	  this.sidebar.select('a').each(function(link) {
      if (new RegExp(elem.value).test(link.href)) {
  	    link.href = link.href.replace('&ids[]=' + elem.value, '');
      }
      else{
        link.href = link.href + '&ids[]=' + elem.value;
      }
	  });
	  
	  // update action drop-down elements
	  this.dropdown.select('option.applications').each(function(option) {
      if (new RegExp(elem.value).test(option.value)) {
  	    option.value = option.value.replace('&ids[]=' + elem.value, '');
      }
      else{
        option.value = option.value + '&ids[]=' + elem.value;
      }
	  });
	}
};