/*------------------------------------------------------------*/
/* 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 '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;
}

/*------------------------------------------------------------*/


if (!window.Element) {
  var Element = new Object();
}

if (!window.Form) {
  var Form = new Object();
}

Object.extend(Form, { 
  // Clear search string from a form 
  wipe: function(form){
    if(form.value == 'Search...') form.value = ''
  }
});


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);




/*-------------------- 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() {
    Element.hide('flash-errors');
    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 = message;
    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 = message;
    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.name = name;
    
    new Ajax.Updater(this.content, url, {onComplete: this.onAppear.bind(this)} );        
    new Display.appear(this.overlay, {duration: 0.5, to: 0.8});        
    
    Dialog.instances.push(this);
  },
  
  onAppear: function() {
    this.content.addClassName(this.name);
    this.content.show();
  },
  
  close: function() {
    this.content.hide();
    this.content.removeClassName(this.name);
    new Effect.Fade(this.overlay, {duration: 0.5});
  }
}  

/*-------------------- 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(document.getElementsByClassName('featured', image).length != 0)
        image.removeChild(document.getElementsByClassName('featured', image)[0]);
    });
        
    current.style.position = "relative";
    current.appendChild(star);
  },
  
  makeImagesSortable: function() {
    if (!$('image_list')) { return }
    Sortable.create('image_list', { 
      constraint:false, 
      handle:'image_handle', 
      onUpdate: function() {
        new Ajax.Request("/admin/products/"+Product.product_id+"/images;reorder", {
          method: 'POST', parameters: 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) {
    document.getElementsByClassName('sortable-related','variant_list').each(function(handle){
       Element.toggle(handle);
     });
     Sortable.create('variant_list',
       { handle:'drag-handle', 
         onUpdate:function(){new Ajax.Request('/admin/products/'+productID+'/variants;reorder', { parameters: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: 'collect[product_id]='+this.product_id+'&collect[collection_id]='+collection_id, onSuccess: highlight} );
    }
    else {    
      new Ajax.Request('/admin/collects/'+this.product_id+'-'+collection_id, {method: 'DELETE', onSuccess: highlight});
    }    
  }
  
}

/*-------------------- Collection Administration Functions ------------------------------*/

var Collection = {
  
  toggleType: function(type) {
    if(type == 'smart') {
      $('smart-form').show();
     } else {
       $('smart-form').hide();
     }
    
  },
	
	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: '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: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: 'product='+ element.id,
              insertion: Insertion.Top, 
              onComplete:function(request) {
                new Effect.Highlight('assoc_'+element.id);
                Collection.createSortable(label_id,labelname)}
              }); 
              return false;
            }
          });

  }
}

/*---------------------------------------------------------------------*/
var SmartForm = {
  line_id: 0,
  
  addLine: function(field, relation, conditions) {
    this.line_id++;
    new Insertion.Bottom('smartcollectionform', this.template(this.line_id));
    var line = $('line-' + this.line_id);
    new SmartForm.CollectionLine(line, field, relation, conditions);
  },

  removeLine: function(id) {
    var length = $$('li.condition-line').length;
    if(length > 1) Element.remove('line-'+id);
  },

  template: function(id) {
    return '' +
    '<li id="line-'+id+'" class="condition-line">' +
      '<span class="smart-tools">' + 
        '<a href="#" onclick="SmartForm.addLine(); return false;"><img alt="Add" src="/images/admin/icons/add.gif" /></a>' + 
        '<a class="del" href="#" onclick="SmartForm.removeLine('+id+'); return false;" title="Remove this"><img alt="Delete" src="/images/admin/icons/delete.gif" /></a>' + 
      '</span>' +      
      '<select name="rules[field][]" style="width: 120px" class="field">' +
        '<option value="title">Product title</option>' +
        '<option value="type">Product type</option>' +
        '<option value="vendor">Product vendor</option>' +
        '<option value="variant_price">Product price</option>' +
        '<option value="variant_compare_at_price">Compare at price</option>' +
        '<option value="variant_weight">Weight</option>' +
        '<option value="variant_inventory">Inventory stock</option>' +
        '<option value="variant_title">Variant\'s title</option>' +
      '</select>' +
      '' +
      '<select name="rules[relation][]" style="display:none;width: 120px" class="relation">' +
        '<option value="equals">is equal to</option>' +
        '<option value="greater_than">is greater than</option>' +
        '<option value="less_than">is less than</option>' +
      '</select>' +
      '' +
      '<select name="rules[str_relation][]" style="display:none; width: 120px" class="strrelation">' +
        '<option value="equals">is equal to</option>' +
        '<option value="contains">contains</option>' +
        '<option value="starts_with">starts with</option>' +
        '<option value="ends_with">ends with</option>' +
      '</select>' +
      '' +
      '<input name="rules[condition][]" style="display:none;width: 120px" class="condition" />' +
    '</li>';
  }

}

SmartForm.CollectionLine = Class.create();
SmartForm.CollectionLine.prototype = {  
  
  line: null,

  initialize: function(line, field, relation, conditions) {
    this.line = line;
    
    if (field && relation && conditions ) {
      this.selectByString(this.fieldSelect(), field)
      this.selectByString(this.relationSelect(), relation)
      this.selectByString(this.strRelationSelect(), relation)
      this.conditionsInput().value = conditions;
    }

    this.registerObservers();
    this.onFieldChange(null, this.fieldSelect().value);
  },

  registerObservers: function() {
    new Form.Element.EventObserver(this.fieldSelect(this.line), this.onFieldChange.bind(this));
  },

  selectByString: function(element, value) {
    for(var i = 0; i < element.options.length; i++) {
      if (element.options[i].value == value) {
       element.selectedIndex = i;
       return;
    }}
  },

  onFieldChange: function(element, value) {

    this.hideEverything();
    
    if (this.typeOfField(value) == 'string') {
      this.onStringTypeSelect();
    }
    else {
      this.onNumberTypeSelect();  
    }
  },

  typeOfField: function(value) {
    switch(value.toLowerCase()) {
      case 'title': 
      case 'type':
      case 'vendor':
      case 'variant_title':
        return 'string';
      case 'variant_price':  
      case 'variant_compare_at_price':
      case 'variant_weight':
      case 'variant_inventory':
        return 'numeric';
      default: 
        console.warn(value);
    }    
    return null;
  },

  onStringTypeSelect: function() {
    Element.show(this.strRelationSelect(this.line));
    Element.show(this.conditionsInput(this.line));
  },

  onNumberTypeSelect: function(element) {
    Element.show(this.relationSelect(this.line));
    Element.show(this.conditionsInput(this.line));
  },

  fieldSelect: function() {
    return document.getElementsByClassName('field', this.line)[0];
  },

  relationSelect: function() {
    return document.getElementsByClassName('relation', this.line)[0];
  },

  strRelationSelect: function() {
    return document.getElementsByClassName('strrelation', this.line)[0];
  },

  conditionsInput: function() {
    return document.getElementsByClassName('condition', this.line)[0];
  },

  hideEverything: function(element) {
    Element.hide(this.conditionsInput());
    Element.hide(this.relationSelect());
    Element.hide(this.strRelationSelect());
  }
}


/*--------------------------------------------------------------------*/

//Display controls the visual appearance of elements on the screen.
//It's 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);
    }
  },

  //Hides elements by className.
  //TODO: Allow the ability to exclude elements by Id
  hideByClassName: function(className) {
    var elements = document.getElementsByClassName(className);
    if(elements.length > 1) 
      this.hideGroup(elements);
    else
      this.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) { with(Element) {
      setOpacity(effect.element, effect.options.from);
      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]);
      }
    }
  });



/*----------------------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 = document.getElementsByClassName('tools', this.toolbox)[0];
    if(!tools) { throw "You called new ToolBox() on an element which has no class=\"tools\" child element"; }
    return tools;
  }
}


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);
    Event.stop(event);
  },

  toggleTag: function(tag) {
    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().toLowerCase().gsub(/[^a-z0-9\-]/, '');
    }).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)) {
        Element.addClassName(a, "active"); 
      }
      else  { 
        Element.removeClassName(a, "active"); 
      }
    });        
  }  
};

var LinkForm = {
  toggleSortable: function(name, list_id) {        
    document.getElementsByClassName('drag-handle', $(name)).each( function(handle) {Element.toggle(handle)} );
    Sortable.create($(name), { 
        handle:   'drag-handle', 
        onUpdate: function(){
          new Ajax.Request('/admin/links/reorder/'+list_id, { parameters:Sortable.serialize(name) })
        }
      }
    );
    
    Element.togglePair('reorder-list-'+ list_id, 'apply-listorder-' + list_id)
  },
  
  toggleTags: function(parent) {
    var input  = document.getElementsByClassName('choose-tags', parent)[0];
    var span   = document.getElementsByClassName('with-tags', parent)[0];
    
    if(span.visible()) {
      span.hide(); 
      input.show();
    } else { 
      span.show(); 
      input.hide();
    }
  }      
}

LinkForm.LinkList = Class.create();
LinkForm.LinkList.prototype = {
  list: null,
  
  initialize: function(list) {
    this.list = $(list);
    Event.observe(this.element('selector'), 'change', function() { 
      this.showCorrectDetail(); 
      return true;
    }.bind(this) );
    this.showCorrectDetail();
  },
       
  showCorrectDetail: function() {
    var element = this.element('selector');
    
    this.allElements('details').each(
      function(e) { Element.hide(e) }
    );
    
    detail_span = this.element($F(element) + '-detail')
    if (detail_span) { Element.show(detail_span); }        
  },
  
  element: function(klass) {
    return document.getElementsByClassName(klass, this.list).first();
  },

  allElements: function(klass) {
    return document.getElementsByClassName(klass, this.list).flatten();
  }       
}   


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) {
    $('shop_province').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) {
    this.prefix = prefix;
    this.select = $(this.prefix + '_gateway_name');        
    Event.observe(this.select, 'change', this.gatewayChange.bind(this));
    this.gatewayChange();
  },

  gatewayChange: function() {
    var name = this.prefix + '-' + this.select.value;
    $$('.' + this.prefix + '-properties').each(function(element) {
      element.hide();
    });

    if(this.select.value == "") {
      return;
    } else {
      $(name).show();
    }
  }
};

ManualGatewayForm = Class.create();
ManualGatewayForm.prototype = {
  initialize: function(selected) {
    this.insertPath = '/admin/preferences/payment/insert_manual_gateway';
    this.select = $('manual_payment_gateway');
    this.selected = selected;
    this.defaults = ['Money Order', 'Cash on Delivery (COD)', 'Bank Deposit'];
    this.customLabelField = $('custom_manual_gateway_label');
    this.customLabelFields = $('custom_manual_gateway_fields');
    Event.observe(this.select, 'change', this.gatewayChange.bind(this));
    this.gatewayChange();
    this.removeSelected();
  },

  removeGatewayOption: function() {
    var selected = this.select.value;
    var selectedOption = this.select.options[this.select.selectedIndex];
    if (selectedOption.value != 'custom'){
      selectedOption.remove();
    }
  },

  removeSelected: function() {
    var options = $A(this.select.options);
    this.selected.each(function(value) {
      options.each(function(option) {
        if (option.value == value) {
          option.remove();
        }
      }); 
    });
  },

  insertForm: function(name) { 
    var queryString = 'name=' + encodeURIComponent(name);
    new Ajax.Request(this.insertPath, { parameters:queryString, onComplete:this.removeGatewayOption.bind(this) });
  },

  gatewayChange: function() {
    if(this.select.value == 'custom') {
      var name = prompt("Enter a name for the manual gateway:","");
      if (name != null && name != "") {
        this.insertForm(name);
      }
    }
    else {
      var selected = this.select.value;
      if (selected == '') {
        return;
      }
      else {
        this.insertForm(this.select.value);
      }
    }
  },

  deleteGateway: function(id, name, element) {
    if (confirm('Are you sure you want to delete this gateway?')) {
      var ggParent = element.parentNode.parentNode.parentNode;
      var gggParent = ggParent.parentNode;
      
      if (id) {
        // Schedule for deletion of existing gateway
        label = document.getElementsByClassName('manual-label', ggParent).first();
        label.innerHTML = '<s>' + label.innerHTML + '</s>';
        
        document.getElementsByClassName('show-on-delete', ggParent).invoke('show');
        document.getElementsByClassName('hide-on-delete', ggParent).invoke('hide');
        this.scheduleForDeletion(name);
      } else {
        // Remove new gateway immediately
        Element.remove(gggParent);
        if (this.defaults.include(name)) {
          this.select.options.add(new Option(name, name), 2);
        }
      }
    }
  },

  scheduleForDeletion: function(name) {
    form = $('gateways-form');
    field = document.createElement('input');
    field.type = 'hidden';
    field.name = 'manual_gateways_to_destroy[' + name + ']';
    form.appendChild(field);
  },

  toggleDetails: function(element) {
    var ggggParent = element.parentNode.parentNode.parentNode.parentNode.parentNode;
    details = document.getElementsByClassName('details', ggggParent);
    details.invoke('toggle');    
    element.innerHTML = details.all(Element.visible) ? '(Hide details)' : '(Show details)';
  }
};