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 && StyleWriter) new StyleWriter().createStyle(styles);
    else if ($type(option) == 'function') option(styles, text);
    return text;
  },

  parseURL: function(query){
    var url=this,
            rx=/^((?:ht|f|nn)tps?)\:\/\/(?:([^\:\@]*)(?:\:([^\@]*))?\@)?([^\/]*)([^\?\#]*)(?:\?([^\#]*))?(?:\#(.*))?$/,
            rg=[null,'scheme','user','pass','host','path','query','fragment'],
            r=url.match(rx),i,q,ret={};
    if (r==null) return ret;
    for (i=1; i<rg.length; i++)
            if (r[i]!=undefined)
                    ret[rg[i]]=r[i];
    if (ret.path=='') ret.path='/';
    if (query!=undefined)
      if(r[6]!=undefined) {
            var q=r[6];
            ret.query={};
            q=q.split('&');
            for (var i=0; i<q.length; i++) {
                    q[i]=q[i].split('=',2);
                    ret.query[unescape(q[i][0])]=unescape(q[i][1]);
            }
      } else ret.query = {};
    return $H(ret);
  },

  updateQueryValue: function(name, value){
    var params = this.parseQuery() || {};
    params[name]=value;
    return Hash.toQueryString(params);
  },

  updateUrlValue: function(name, value){
    var url = this.parseURL(1);
    url["query"][name] = value;
    return url.glueURL();
  },

  updateUrlValues: function(params){
    var url = this.parseURL(1);
    url["query"] = $merge(url["query"], params);
    return url.glueURL();
  },

  getUrlValue: function(name){
    return this.parseURL(1)["query"][name] || '';
  }

})

Hash.implement({
  glueURL: function(){
    var query=this;
    var uri='';
    uri = query['scheme'] ? query['scheme']+':'+((query['scheme'].toLowerCase == 'mailto') ? '':'//'): '';
    uri += query['user'] ? query['user']+(query['pass']? ':'+query['pass']:'')+'@':'';
    uri += query['host'] ? query['host'] : '';
    uri += query['port'] ? ':'+query['port'] : '';
    uri += query['path'] ? query['path'] : '';
    uri += query['query'] ? '?'+($type(query["query"])=="object"? Hash.toQueryString(query['query']):query['query']) : '';
    //uri += query['fragment'] ? '#'+query['fragment'] : '';
    if(uri =='' && Hash.getLength(query)>0)  uri = Hash.toQueryString(query);
    return uri;
  }
});

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

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

  getFormHash: function(){
    var formHash = {};
    $(this).getFormElements().each(function(el){
      if (!el.name || el.disabled) 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) formHash[el.name] = encodeURIComponent(val);
      });
    });
    return formHash;
  },

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

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


  effect: function(property, options){
    return new Fx.Tween(this, $extend({property: property}, options));
  },
  show: function(display) {
    original = this.retrieve('originalDisplay')?this.retrieve('originalDisplay'):this.get('originalDisplay');
    if (Browser.Engine.gecko) orig = {table: 'table', tr: 'table-row', td: 'table-cell'}[this.get('tag')];
      else orig='';
    this.setStyle('display',(display || original || orig || 'block'));
    return this;
  }


})

Element.Properties.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;
}


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){
  $H(vars).each(function(v, k){
    var el = $f(k);
    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){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){

  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;
      window.addEvent('scroll', function(){
        var el = $(element);
        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
            cart_fx.start((ws.scroll.y-top+10).limit(0, 10000000));
          } else { // DOWN
            cart_fx.start(((ws.scroll.y+ws.size.y)-(top+cart.height)-10).limit(0, 10000000));
          }
        } else {
          cart_fx.start((ws.scroll.y-top+10).limit(0, 10000000));
        }
        old_scroll=ws.scroll.y;
      });
  }
}
