String.implement({

  stripStyles: function(option){
    var styles = '';
    var text = this.replace(/<style[^>]*>([\s\S]*?)<\/style>/gi, function(){
      styles += arguments[1] + '\n';
      return '';
    });
    if (option === true && styles && StyleWriter) new StyleWriter().createStyle(styles);
    else if ($type(option) == 'function') option(styles, text);
    return text;
  },

  updateUrlValue: function(name, value){
    return this.toURI().setData(name, value).toString();
  },

  updateUrlValues: function(params){
    return this.toURI().setData(params, true).toString();
  },

  getUrlValue: function(name, part){
    return this.toURI().getData(name, part);
  },
  
  trim: function(chars){
    if (!chars) chars = '\\s+';
    var reg = new RegExp('^'+chars+'|'+chars+'$', 'g');
    return this.replace(reg, '');
  }

});

Array.implement({
  diff: function(a){
     return this.filter(function(i) {return !(a.indexOf(i) > -1);});
  },
  toInt: function(){
     for (var i = 0, l = this.length >>> 0; i < l; i++){
        if (i in this) this[i]=('0'+this[i]).toInt();
     }
     return this;
  },
  toFloat: function(){
     for (var i = 0, l = this.length >>> 0; i < l; i++){
        if (i in this) this[i]=('0'+this[i]).toFloat();
     }
     return this;
  }

});

Window.implement({
  isLoaded: window.loaded,
  qs: {}
});
//window.qs = window.getQueryStringValues();

Element.implement({
  getFormElements: function(){
    return this.getElements('input, textarea, select');
  },

  getFormHash: function(elements){
    var formHash = {};
    if (!elements) elements = $(this).getFormElements();
    elements.each(function(el){
      if (!el.name) return;
      if (el.get('tag').toLowerCase() == 'select')
        var value = (el.getSelected()).map(function(opt){
          return opt.value;
        })
      if ((el.type == 'radio' || el.type == 'checkbox') && !el.checked)  var value = null;
        else var value = el.value;
      $splat(value).each(function(val){
        if (val==el.get('placeholder')) val=null;
        if (val) formHash[el.name] = encodeURIComponent(val);
      });
    });
    return formHash;
  },
  getFormChanges: function(optionsasarray){
    var formHash = {};
    $(this).getFormElements().each(function(el){
      if (!el.name) return;
      var val;
        switch (el.type) {
                    case 'text' :
                    case 'textarea' :
                    case 'hidden' :
                            if (!/^\s*$/.test(el.value) && el.value != el.defaultValue && el.value!=el.get('placeholder')) formHash[el.name] = el.value;
                            break;
                    case 'checkbox' :
                    case 'radio' :
                            if (el.checked != el.defaultChecked) formHash[el.name] = el.checked?el.value:'';
                            break;
                    case 'select' :
                    case 'select-one' :
                    case 'select-multiple' :
                            j = 0, hasDefault = false;
                            var o = {};
                            while (opt = el.options[j++]) {
                               if (opt.selected != opt.defaultSelected) o[opt.value]= opt.selected?opt.value:'';
                               if (opt.defaultSelected) hasDefault = 1;

                            }
                            if (!hasDefault && el.type!='select-multiple' && el.options.length>1 && el.selectedIndex==0) {
                               delete o[el.options[0].value];
                            }

                            if (o) {
                              if (!optionsasarray) o = Object.values(o).erase('').join(',');
                              if (o) formHash[el.name] = o;
                            }                             
                            break;
        }
    });
    return formHash;
  },

  
  setFormHash: function(formHash){
    formHash = new Hash(formHash);
    $(this).getFormElements().each(function(el){
      if (!el.name || !formHash[el.name]) return;
      el.set("inputValue", decodeURIComponent(formHash[el.name]));
    });
    return formHash;
  },

  clearValue: function(){
    switch(this.get('tag')){
      case 'select':
        $each(this.options, function(option){
          if (option.selected) option.selected = false;
        });
      case 'input':
        if (['text', 'hidden' /*, 'submit', 'button'*/].contains(this.type)) this.value = '';
        if (this.checked || ['checkbox', 'radio'].contains(this.type)) this.checked = false;
        break;
      case 'textarea': this.value = '';
    }
    return this;
  },

  clearFormElements: function(){
    this.getFormElements().each(function(el){ el.clearValue() });
    return this;
  },


  effect: function(property, options){
    return new Fx.Tween(this, $extend({property: property}, options));
  },

  disable: function(){
    $(this).getFormElements().each(function(el){
      el.set('disabled', true);
    });
    return this;
  },

  enable: function(){
    $(this).getFormElements().each(function(el){
      el.set('disabled', false);
    });
    return this;
  },

  show: function(display) {
    original = this.retrieve('originalDisplay')?this.retrieve('originalDisplay'):this.get('originalDisplay');
    if (Browser.Engine.name=='unknown' || Browser.Engine.gecko || Browser.Engine.webkit) orig = {table: 'table', tr: 'table-row', td: 'table-cell'}[this.get('tag')];
      else orig='';
    this.setStyle('display',(display || original || orig || 'block'));
    return this;
  },
  inViewport : function(axis){
        if(!axis){
            return this.inViewport('x') && this.inViewport('y');
        };
        var position = this.getPosition();
        var size = this.getSize();
        var viewport = $(window).getSize();
        var offset = position[axis] + size[axis];
        return (offset < viewport[axis]);
  },
  inWindow : function(axis){
        if(!axis){
            return this.inWindow('x') && this.inWindow('y');
        };
        var position = this.getPosition();
        var scroll = $(window).getScroll();
        return (position[axis] > scroll[axis]);
  }


})

Element.Properties.inputValue = {

    get: function(){
       switch(this.get('tag')) {
        case 'select':
          vals = this.getSelected().map(function(op){
            var v = $pick(op.get('value'),op.get('text'));
            return (v=="")?op.get('text'):v;
          });
          return this.get('multiple')?vals:vals[0];
        case 'input':
          switch(this.get('type')) {
            case 'checkbox':
              return this.get('checked')?this.get('value'):false;
            case 'radio':
              var checked;
              if (this.get('checked')) return this.get('value');
              $(this.getParent('form')||document.body).getElements('input').each(function(input){
                if (input.get('name') == this.get('name') && input.get('checked')) checked = input.get('value');
              }, this);
              return checked||null;
          }
        case 'input': case 'textarea':
          return this.get('value');
        default:
          return this.get('inputValue');
       }
    },

    set: function(value){
       switch(this.get('tag')){
         case 'select':
           this.getElements('option').each(function(op){
             var v = $pick(op.get('value'), op.get('text'));
             if (v=="") v = op.get('text');
             op.set('selected', $splat(value).contains(v));
           });
           break;
         case 'input':
           if (['radio','checkbox'].contains(this.get('type'))) {
             this.set('checked', $type(value)=="boolean"?value:$splat(value).contains(this.get('value')));
             if (this.get('type')=="radio" && !this.get('checked'))
               $(this.getParent('form')||document.body).getElements('input').each(function(input){
                 if (input.get('name') == this.get('name')) input.set('checked', input.get('value')==value);
               }, this);
             break;
           }
         case 'textarea': case 'input':
           this.set('value', value);
           break;
         default:
           this.set('inputValue', value);
       }
      return this;
    },
    erase: function() {
      switch(this.get('tag')) {
        case 'select':
          this.getElements('option').each(function(op) {
            op.erase('selected');
          });
          break;
        case 'input':
          if (['radio','checkbox'].contains(this.get('type'))) {
            this.set('checked', false);
            break;
          }
        case 'input': case 'textarea':
          this.set('value', '');
          break;
        default:
          this.set('inputValue', '');
      }
      return this;
    }
};

Element.Properties.outerHtml = {
    get: function(){
        var copy = this.clone(); 
        var Outer = new Element('div').adopt(copy); 
        var theHtml = Outer.get('html'); 
        Outer.destroy(); 
        return theHtml;
    }
};


function $f(name, form){
  form = $($(form)||document.body);
  var el = null;
  form.getElements('input,select,textarea').each(function(input){
    if (!el && input.get('name') == name) el = $(input);
  });
  return el || form.getElement('#'+name);
}


function updateFields(vars, form){
  form = $($(form)||document.body);
  $H(vars).each(function(v, k){
    var el = $f(k, form);
    if(el){
      if (el.form) el.set('inputValue', v);
      else if(el.get('tag')=="span") el.set('html', v);
    }
  });
}


function is_true(value){
  if ("string" == typeof(value)) {
    if (value=="0" || value.toLowerCase()=="no" || value.toLowerCase()=="false" || value.length==0) return false;
      else return true;
  }
  if ("number" == typeof(value))
    if (value>0) return true;
      else return false;
  if ("boolean" == typeof(value)) return value;
  if ("undefined" == typeof(value)) return false;
  if ("function" == typeof(value)) return true;
  if ("object" == typeof(value)) return value;
  return false;
}

/*
Script: StyleWriter.js

Provides a simple method for injecting a css style element into the DOM if it's not already present.

License:
  http://clientside.cnet.com/wiki/cnet-libraries#license
*/

var StyleWriter = new Class({
  createStyle: function(css, id) {
    window.addEvent('domready', function(){
      try {
        if($(id) && id) return;
        var style = new Element('style', {id: id||''}).inject($$('head')[0]);
        if (Browser.Engine.trident) style.styleSheet.cssText = css;
        else style.set('text', css);
      }catch(e){if (dbug && dbug["log"]) dbug.log('error: %s',e);}
    }.bind(this));
  }
});

/*
var Request = new Class({
  Implements: [Chain, Events, Options],

  response: {},
  options: {
    url: '',
    data: '',
    method: 'post'
  },

  initialize: function(options){
    this.setOptions(options);
  },

  onStateChange: function(){},
  isSuccess: function(){},
  processScripts: function(text){},
  success: function(text, xml){
    this.onSuccess(text, xml);
  },
  onSuccess: function(){
    this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
  },
  failure: function(){
    this.onFailure();
  },
  onFailure: function(){
    this.fireEvent('complete').fireEvent('failure');
  },
  send: function(options){},
  cancel: function(){}
});

*/
Request.SMS = new Class({
  Extends: Request,
  options: {
    sms: ''
  },

  initialize: function(options){
    this.parent(options);
  },
  send: function(options){
    var type = $type(options);
    if (type == 'string' || type == 'element') options = {data: options};

    var old = this.options;
    options = $merge({data: old.data, sms: old.sms, method: old.method}, options);
    var data = options.data, sms = options.sms, method = options.method;
    switch ($type(data)){
      case 'element': data = $(data).toQueryString(); break;
      case 'object': case 'hash': data = Hash.toQueryString(data);
    }
    send_sms(sms, data, this.success.bind(this));
  },

  success: function(json, text){
    this.onSuccess(json, text);
  }

});

function stick_div(element, top_limit){
  top_limit = top_limit+0;
  var elem = $(element);
  //if (!elem) return arguments.callee.delay(500);
  if (!Browser.Engine.trident4 && elem){
      var cart_fx = new Fx.Tween(elem, {property:'margin-top', transition: Fx.Transitions.Quad.easeInOut, duration: 1000, link: 'cancel'});
      var old_scroll = 0;
      var top=0;
      var mtop = elem.getStyle('margin-top').toInt();
      var el = $(element);
      $(window).addEvent('scroll', function(){
        if (noFollow) return;
        var go = 0;
        var ws = {size: window.getSize(), scroll:window.getScroll()};
        var cart_pos = el.getPosition();
        if (!top) top= cart_pos.y;
        var cart = el.getCoordinates();
        if (ws.size.y<cart.height){
          if (old_scroll> ws.scroll.y){ //up SCROLL
            go = (ws.scroll.y-top+mtop).limit(mtop, 10000000);
            cart_fx.start(go);
          } else { // DOWN
            go = ((ws.scroll.y+ws.size.y)-(top+cart.height)-mtop).limit(mtop, 10000000);
            cart_fx.start(go);
          }
        } else {
          go = (ws.scroll.y-top+mtop*2).limit(mtop, 10000000);
          cart_fx.start(go);
        }
        old_scroll=ws.scroll.y;
      });
      $(window).fireEvent('scroll');
  }
}

spins = [];
spindelay = [];
function e24spin(el, ttl, options){
    if (el){
        el.spin(options);
        spins[spins.length] = el;
    }
    if (ttl>0) spindelay[spindelay.length] = e24unspin.delay(ttl);
    if ($('loading')) $('loading').show().position({position: 'centerTop'}).pin(true, true);
}

function e24unspin(){
    spins.each(function(el){
      el.unspin();
    });
    spindelay.each(function(timer){clearTimeout(timer);});
    if ($('loading')) $('loading').hide();
    spins.empty();
    spindelay.empty();
}


/* Tips */
window.addEvent('domready', function(){
  var Tips1 = new Tips($$('.tips'),{
     fixed: true
  });
  
  if (typeof(NS)!="undefined" && NS.Placeholder) {
    new NS.Placeholder({
            color: '#aaa'
        });
  }
});

