/**
  *
  *  Copyright 2005 Sabre Airline Solutions
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
  *  file except in compliance with the License. You may obtain a copy of the License at
  *
  *         http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software distributed under the
  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  *  either express or implied. See the License for the specific language governing permissions
  *  and limitations under the License.
  **/


// This module does NOT depend on prototype.js

var Rico = {
  Version: '2.0 beta2',
  loadRequested: 1,
  loadComplete: 2,
  init : function() {
    try {  // fix IE background image flicker (credit: www.mister-pixel.com)
      document.execCommand("BackgroundImageCache", false, true);
    } catch(err) {}
    this.preloadMsgs='';
    var elements = document.getElementsByTagName('script');
    this.baseHref= location.protocol + "//" + location.host;
    this.loadedFiles={};
    this.loadQueue=[];    
    this.windowIsLoaded=false;
    this.onLoadCallbacks=[];
    for (var i=0; i<elements.length; i++) {
      if (!elements[i].src) continue;
      var src = elements[i].src;
      var slashIdx = src.lastIndexOf('/');
      var path = src.substring(0, slashIdx+1);
      var filename = src.substring(slashIdx+1);
      this.loadedFiles[filename]=this.loadComplete;
      var parmPos  = filename.indexOf('?');
      if (parmPos > 0)
        filename = filename.substring(0, parmPos)
      if (filename == 'rico.js') {
        var isRailsPath = (path.indexOf("/javascripts") > 0)
        if (isRailsPath){
          this.jsDir = "/javascripts/";
          this.cssDir = "/stylesheets/";
          this.imgDir = "/images/";   
          this.htmDir = "/";
          this.xslDir = "/";
        } else {
          this.jsDir = path;
          this.cssDir = path+'css/';
          this.imgDir = path+'images/';
          this.htmDir = path;
          this.xslDir = path;
        }
      }
    }
    if (typeof Prototype=='undefined')
      this.include('prototype.js');
    var func=function() { Rico.windowLoaded(); };
    if (window.addEventListener)
      window.addEventListener('load', func, false);
    else if (window.attachEvent)
      window.attachEvent('onload', func);
    this.onLoad(function() { Rico.writeDebugMsg('Pre-load messages:\n'+Rico.preloadMsgs); });
  },
  
  // Array entries can reference a javascript file or css stylesheet
  // A dependency on another module can be indicated with a plus-sign prefix: '+DependsOnModule'
  moduleDependencies : {
    Accordion  : ['ricoBehaviors.js','ricoEffects.js','ricoComponents.js'],
    Color      : ['ricoColor.js'],
    Corner     : ['ricoStyles.js'],
    DragAndDrop: ['ricoDragDrop.js'],
    Effect     : ['ricoEffects.js'],
    Calendar   : ['ricoCalendar.js', 'ricoCalendar.css'],
    Tree       : ['ricoTree.js', 'ricoTree.css'],
    ColorPicker: ['ricoColorPicker.js', 'ricoStyles.js', 'ricoColorPicker.css'],
    SimpleGrid : ['ricoCommon.js', 'ricoGridCommon.js', 'ricoGrid.css', 'ricoSimpleGrid.js'],
    LiveGrid   : ['ricoCommon.js', 'ricoGridCommon.js', 'ricoGrid.css', 'ricoBehaviors.js', 'ricoLiveGrid.js'],
    CustomMenu : ['ricoMenu.js', 'ricoMenu.css'],
    LiveGridMenu : ['+CustomMenu', 'ricoLiveGridMenu.js'],
    LiveGridAjax : ['+LiveGrid', 'ricoLiveGridAjax.js'],
    LiveGridForms: ['+LiveGridAjax', '+LiveGridMenu', '+Accordion', '+Corner', 'ricoLiveGridForms.js', 'ricoLiveGridForms.css'],
    SpreadSheet  : ['+SimpleGrid', 'ricoSheet.js']
  },
  
  // Expects one or more module or file names
  // not reliable when used with XSLT
  loadModule : function() {
    for (var a=0, length=arguments.length; a<length; a++) {
      var name=arguments[a];
      var dep=this.moduleDependencies[name];
      if (dep) {
        for (var i=0; i<dep.length; i++)
          if (dep[i].substring(0,1)=='+')
            this.loadModule(dep[i].slice(1));
          else
            this.include(dep[i]);
      } else {
        this.include(name);
      }
    }
  },
  
  // not reliable when used with XSLT
  include : function(filename) {
    if (this.loadedFiles[filename]) return;
    this.addPreloadMsg('include: '+filename);
    var ext = filename.substr(filename.lastIndexOf('.')+1);
    switch (ext.toLowerCase()) {
      case 'js':
        this.loadQueue.push(filename);
        this.loadedFiles[filename]=this.loadRequested;
        this.checkLoadQueue();
        return;
      case 'css':
        var el = document.createElement('link');
        el.type = 'text/css';
        el.rel = 'stylesheet'
        el.href = this.cssDir+filename;
        this.loadedFiles[filename]=this.loadComplete;
        document.getElementsByTagName('head')[0].appendChild(el);
        return;
    }
  },
  
  checkLoadQueue: function() {
    if (this.loadQueue.length==0) return;
    if (this.inProcess) return;  // seems to only be required by IE, but applied to all browsers just to be safe
    this.addScriptToDOM(this.loadQueue.shift());
  },
  
  addScriptToDOM: function(filename) {
    this.addPreloadMsg('addScriptToDOM: '+filename);
    var js = document.createElement('script');
    js.type = 'text/javascript';
    js.src = this.jsDir+filename;
    this.loadedFiles[filename]=this.loadRequested;
    this.inProcess=filename;
    var head=document.getElementsByTagName('head')[0];
    if (filename.substring(0,4)=='rico') {
      head.appendChild(js);
    } else if (this.isKonqueror) {
      throw("Cannot load non-Rico js files dynamically in Konqueror");
    } else if(/WebKit|Khtml/i.test(navigator.userAgent)) {
      head.appendChild(js);
      this.includeLoaded(filename);
    } else {
      js.onload = js.onreadystatechange = function() {
        if (js.readyState && js.readyState != 'loaded' && js.readyState != 'complete') return;
        js.onreadystatechange = js.onload = null;
        Rico.includeLoaded(filename);
      };
      head.appendChild(js);
    }
  },
  
  // called after a script file has finished loading
  includeLoaded: function(filename) {
    this.addPreloadMsg('loaded: '+filename);
    this.loadedFiles[filename]=this.loadComplete;
    if (filename==this.inProcess) {
      this.inProcess=null;
      this.checkLoadQueue();
      this.checkIfComplete();
    }
  },

  // called by the document onload event
  windowLoaded: function() {
    this.windowIsLoaded=true;
    this.checkLoadQueue();
    this.checkIfComplete();
  },
  
  checkIfComplete: function() {
    var waitingFor=this.windowIsLoaded ? '' : 'window';
    for(var filename in  this.loadedFiles) {
      if (this.loadedFiles[filename]==this.loadRequested)
        waitingFor+=' '+filename;
    }
    //window.status='waitingFor: '+waitingFor;
    this.addPreloadMsg('waitingFor: '+waitingFor);
    if (waitingFor.length==0) {
      this.addPreloadMsg('Processing callbacks');
      while (this.onLoadCallbacks.length > 0) {
        var callback=this.onLoadCallbacks.pop();
        if (callback) callback();
      }
    }
  },
  
  onLoad: function(callback) {
    this.onLoadCallbacks.push(callback);
    this.checkIfComplete();
  },

  isKonqueror : navigator.userAgent.toLowerCase().indexOf("konqueror") >= 0,

  // logging funtions
   
  startTime : new Date(),

  timeStamp: function() {
    var stamp = new Date();
    return (stamp.getTime()-this.startTime.getTime())+": ";
  },
  
  setDebugArea: function(id, forceit) {
    if (!this.debugArea || forceit) {
      var newarea=document.getElementById(id);
      if (!newarea) return;
      this.debugArea=newarea;
      newarea.value='';
    }
  },

  addPreloadMsg: function(msg) {
    this.preloadMsgs+=Rico.timeStamp()+msg+"\n";
  },

  writeDebugMsg: function(msg, resetFlag) {
    if (this.debugArea) {
      if (resetFlag) this.debugArea.value='';
      this.debugArea.value+=this.timeStamp()+msg+"\n";
    }
  }

}

Rico.init();

 /**
   *  (c) 2005-2007 Richard Cowin (http://openrico.org)
   *
   *  Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
   *  file except in compliance with the License. You may obtain a copy of the License at
   *   http://www.apache.org/licenses/LICENSE-2.0
   **/

Rico.animate = function(effect){
	new Rico.Effect.Animator().play(effect, arguments[1]);
}

Rico.Effect = {}
Rico.Effect.easeIn = function(step){
  return Math.sqrt(step)
}
Rico.Effect.easeOut = function(step){
  return step*step
}
Rico.Stepping = {}
Rico.Stepping.easeIn = Rico.Effect.easeIn;
Rico.Stepping.easeOut = Rico.Effect.easeOut;

Rico.Effect.Animator = Class.create();
Rico.Effect.Animator.prototype = {
	initialize : function(effect) {
		this.animateMethod = this.animate.bind(this);
		this.options = arguments[1] || {};
		this.stepsLeft = 0;
		if (!effect) return;
		this.reset(effect, arguments[1]);
	},
	reset: function(effect){
		this.effect = effect;
    if (arguments[1]) this.setOptions(arguments[1]);
		this.stepsLeft = this.options.steps;
		this.duration = this.options.duration;
	},
	setOptions: function(options){
	  this.options = Object.extend({
			steps: 10,
			duration: 200,
			rate: function(steps){ return steps;}
    }, options|| {});
	},
	play: function(effect) {
	  this.setOptions(arguments[1])
	  if (effect)
  	  if (effect.step)
  		  this.reset(effect, arguments[1]);
  		else{
  		  $H(effect).keys().each((function(e){
  		    var effectClass = {fadeOut:Rico.Effect.FadeOut}[e];
  		    this.reset(new effectClass(effect[e]));
  		  }).bind(this))		  
  		}
		this.animate();
	},
	stop: function() {
		this.stepsLeft = this.options.steps;
	},
	pause: function() {
		this.interupt = true;
	},
	resume: function() {
	  this.interupt = false;
	  if (this.stepsLeft >0)
	    this.animate();
	},
	animate: function() {
	  if (this.interupt)
	    return;
		if (this.stepsLeft <=0) {
			if (this.effect.finish)  this.effect.finish();
			if (this.options.onFinish) this.options.onFinish();
			return;
		}
		if (this.timer)
			clearTimeout(this.timer);
		this.effect.step(this.options.rate(this.stepsLeft));
		this.startNextStep();
  },
	startNextStep: function() {
		var stepDuration = Math.round(this.duration/this.stepsLeft) ;
    this.duration -= stepDuration;
    this.stepsLeft--;
    this.timer = setTimeout(this.animateMethod, stepDuration);
	},
  isPlaying: function(){
    return this.stepsLeft != 0 && !this.interupt;
  }
}

Rico.Effect.Group = Class.create();
Rico.Effect.Group.prototype = {
  initialize: function(effects){
    this.effects = effects;
  },
  step: function(stepsToGo){ 
    this.effects.each(function(e){e.step(stepsToGo)});
  },
  finish: function(){
    this.effects.each(function(e){if (e.finish) e.finish()});
  }
}

Rico.Effect.SizeAndPosition = Class.create();
Rico.Effect.SizeAndPosition.prototype = {
   initialize: function(element, x, y, w, h) {
      this.element = $(element);
      this.x = x || this.element.offsetLeft;
      this.y = y || this.element.offsetTop;
      this.w = w || this.element.offsetWidth;
      this.h = h || this.element.offsetHeight;
   },
   step: function(stepsToGo) {  
			var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px"
			var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/stepsToGo) + "px"
			var width = this.element.offsetWidth + ((this.w - this.element.offsetWidth)/stepsToGo) + "px"
			var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/stepsToGo) + "px"
      var style = this.element.style;
			style.left = left;
			style.top = top;
			style.width = width;
			style.height = height;
   }
}

Rico.AccordionEffect = Class.create();
Rico.AccordionEffect.prototype = {
  initialize: function(toClose, toOpen, height) {
    this.toClose   = toClose;
    this.toOpen    = toOpen;
/*    if (!navigator.appVersion.match(/\bMSIE\b/)) {*/
      Element.makeClipping(toOpen);
      Element.makeClipping(toClose);
/*    }*/
    Rico.Controls.disableNativeControls(toClose);
    Element.show(toOpen);
    this.toOpen.style.height = "0px";
    this.endHeight = height;
  },
  step: function(framesLeft) {
     var cHeight = Math.max(1,this.toClose.offsetHeight - parseInt((parseInt(this.toClose.offsetHeight))/framesLeft));
     var closeHeight = cHeight + "px";
     var openHeight = (this.endHeight - cHeight) + "px"
     this.toClose.style.height = closeHeight;
     this.toOpen.style.height = openHeight;
  },
  finish: function(){
    Element.hide(this.toClose)
    this.toOpen.style.height = this.endHeight + "px";
    this.toClose.style.height = "0px";
/*    if (!navigator.appVersion.match(/\bMSIE\b/)) {*/
      Element.undoClipping(this.toOpen);
      Element.undoClipping(this.toClose);
/*    }*/

		Rico.Controls.enableNativeControls(this.toOpen);
  }
};

Rico.Effect.SizeFromBottom = Class.create()
Rico.Effect.SizeFromBottom.prototype = {
  initialize: function(element, y, h) {
    this.element = $(element);
    this.y = y || this.element.offsetTop;
    this.h = h || this.element.offsetHeight;
    this.options  = arguments[3] || {};
  },
  step: function(framesToGo) {  
		var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/framesToGo) + "px"
		var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo) + "px"
    var style = this.element.style;
		style.height = height;     
		style.top = top;
  }
}

Rico.Effect.Position = Class.create();
Rico.Effect.Position.prototype = {
  initialize: function(element, x, y) {
    this.element = $(element);
    this.x = x || this.element.offsetLeft;
    this.destTop = y || this.element.offsetTop;
  },
  step: function(stepsToGo) {  
  	var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px"
  	var top = this.element.offsetTop + ((this.destTop - this.element.offsetTop)/stepsToGo) + "px"
    var style = this.element.style;
  	style.left = left;
  	style.top = top;
  }
}

Rico.Effect.FadeTo = Class.create()
Rico.Effect.FadeTo.prototype = {
  initialize: function(element, value){
    this.element = element;
    this.opacity = Element.getStyle(this.element, 'opacity') || 1.0;
    this.target = Math.min(value, 1.0);
  },
  step: function(framesLeft) {
    var curOpacity = Element.getStyle(this.element, 'opacity');
    var newOpacity = curOpacity + (this.target - curOpacity)/framesLeft
    Rico.Effect.setOpacity(this.element, Math.min(Math.max(0,newOpacity),1.0));
  }
}

Rico.Effect.FadeOut = Class.create()
Rico.Effect.FadeOut.prototype = {
  initialize: function(element){
    this.effect = new Rico.Effect.FadeTo(element, 0.0)
  },
  step: function(framesLeft) {
    this.effect.step(framesLeft);
  }
}

Rico.Effect.FadeIn = Class.create()
Rico.Effect.FadeIn.prototype = {
  initialize: function(element){
    var options = arguments[1] || {}
    var startValue = options.startValue || 0
    Element.setStyle(element, 'opacity', startValue);
    this.effect = new Rico.Effect.FadeTo(element, 1.0)
  },
  step: function(framesLeft) {
    this.effect.step(framesLeft);
  }
}

Rico.Effect.setOpacity= function(element, value) {
   element.style.filter = "alpha(opacity:"+Math.round(value*100)+")";
   element.style.opacity = value; 
}

Rico.Effect.SizeFromTop = Class.create()
Rico.Effect.SizeFromTop.prototype = {
  initialize: function(element, scrollElement, y, h) {
     this.element = $(element);
     this.h = h || this.element.offsetHeight;
	//	 element.style.top = y;
     this.scrollElement = scrollElement;
     this.options  = arguments[4] || {};
     this.baseHeight = this.options.baseHeight ||  Math.max(this.h, this.element.offsetHeight)
  },
  step: function(framesToGo) {  
    var rawHeight = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo);
		var height = rawHeight + "px"
		var scroll = (rawHeight - this.baseHeight) + "px";
		this.scrollElement.style.top = scroll;
		this.element.style.height = height;     
  }
}


Rico.Effect.Height = Class.create()
Rico.Effect.Height.prototype = {
  initialize: function(element, endHeight) {
    this.element = element
		this.endHeight = endHeight
  },
  step: function(stepsLeft) {
    if (this.element.constructor != Array){
      var height = this.element.offsetHeight + ((this.endHeight - this.element.offsetHeight)/stepsLeft) + "px"
      this.element.style.height = height;
    } else {
      var height = this.element[0].offsetHeight + ((this.endHeight - this.element[0].offsetHeight)/stepsLeft) + "px"
      this.element.each(function(e){e.style.height = height})
    }
  }
}

Rico.Effect.SizeWidth = Class.create();
Rico.Effect.SizeWidth.prototype = {
    initialize: function(element, endWidth) {
      this.element = element
			this.endWidth = endWidth
    },
    step: function(stepsLeft) {
       delta = Math.abs(this.endWidth - parseInt(this.element.offsetWidth))/(stepsLeft);
       this.element.style.width = (this.element.offsetWidth - delta) + "px";
    }
}

//these are to support non Safari browsers and keep controls from bleeding through on absolute positioned element.
Rico.Controls = {
	editors: [],
	scrollSelectors: [],
	
	disableNativeControls: function(element) {
		Rico.Controls.defaultDisabler.disableNative(element);
  },
	enableNativeControls: function(element){
		Rico.Controls.defaultDisabler.enableNative(element);
	},
	prepareForSizing: function(element){
    Element.makeClipping(element)
    Rico.Controls.disableNativeControls(element)
  },
  resetSizing: function(element){
    Element.undoClipping(element)
    Rico.Controls.enableNativeControls(element)
	},
	registerScrollSelectors: function(selectorSet) {
	  selectorSet.each(function(s){Rico.Controls.scrollSelectors.push(Rico.selector(s))});
	}
}

Rico.Controls.Disabler = Class.create();
Rico.Controls.Disabler.prototype = {
	initialize: function(){
		this.options = Object.extend({
			excludeSet: [],
			hidables: Rico.Controls.editors
    }, arguments[0] || {});
	},
  disableNative: function(element) {
    if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){
			if (!navigator.appVersion.match(/\bMSIE\b/))
				this.blockControls(element).each(function(e){Element.makeClipping(e)});
			else
			  this.hidableControls(element).each(function(e){e.disable()});
    }
  },
  enableNative: function(element){
    if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){
			if (!navigator.appVersion.match(/\bMSIE\b/))
				this.blockControls(element).each(function(e){Element.undoClipping(e)});
			else
			  this.hidableControls(element).each(function(e){e.enable()});
    }
  },
	blockControls: function(element){
	  try{
		var includes = [];
		if (this.options.includeSet)
			includes = this.options.includeSet;
		else{
		  var selectors = this.options.includeSelectors || Rico.Controls.scrollSelectors;
			includes = selectors.map(function(s){return s.findAll(element)}).flatten();
    }
		return includes.select(function(e){return (Element.getStyle(e, 'display') != 'none') && !this.options.excludeSet.include(e)}.bind(this));
  }catch(e) { return []}
	},
	hidableControls: function(element){
		if (element)
			return this.options.hidables.select(function(e){return Element.childOf(e, element)});
		else
			return this.options.hidables;
	}
}	
                    
Rico.Controls.defaultDisabler = new Rico.Controls.Disabler();
Rico.Controls.blankDisabler = new Rico.Controls.Disabler({includeSet:[],hidables:[]});
                 
Rico.Controls.HidableInput = Class.create(); 
Rico.Controls.HidableInput.prototype = {
	initialize: function(field, view){	
		this.field = field;
		this.view = view;
		this.enable();
		Rico.Controls.editors.push(this);
	},
	enable: function(){
		Element.hide(this.view);
		Element.show(this.field);
	},
	disable: function(){
		this.view.value = $F(this.field);
		if (this.field.offsetWidth > 1) {
	    this.view.style.width =  parseInt(this.field.offsetWidth)  + "px";
		  Element.hide(this.field);
		  Element.show(this.view);
	  }
	}
}



Element.forceRefresh = function(item) {
  try {
    var n = document.createTextNode(' ')
    item.appendChild(n); item.removeChild(n);
  } catch(e) { }
};


/**
  *  (c) 2005-2007 Richard Cowin (http://openrico.org)
  *  (c) 2005-2007 Matt Brown (http://dowdybrown.com)
  *
  *  Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
  *  file except in compliance with the License. You may obtain a copy of the License at
  *   http://www.apache.org/licenses/LICENSE-2.0
  **/
  

Rico.ContentTransitionBase = function() {}
Rico.ContentTransitionBase.prototype = {
	initialize: function(titles, contents, options) { 
    if (typeof titles == 'string')
      titles = $$(titles)
    if (typeof contents == 'string')
      contents = $$(contents)
	  
	  this.titles = titles;
	  this.contents = contents;
		this.options = Object.extend({
			duration:200, 
			steps:8,
			rate:Rico.Effect.easeIn
	  }, options || {});
	  this.hoverSet = new Rico.HoverSet(titles, options);
		contents.each(function(p){ if (p) Element.hide(p)})
	  this.selectionSet = new Rico.SelectionSet(titles, Object.extend(this.options, {onSelect: this.select.bind(this)}));
		if (this.initContent) this.initContent();
	},
	reset: function(){
	  this.selectionSet.reset();
	},
	select: function(title) {
	  if ( this.selected == this.contentOf(title)) return
		var panel = this.contentOf(title); 
		if (this.transition){
			if (this.selected){
			  var effect = this.transition(panel)
			  if (effect) Rico.animate(effect, this.options)
      }
			else
				Element.show(panel);
		}else{
			if (this.selected)
				Element.hide(this.selected)
			Element.show(panel);
		}
		this.selected = panel;
	},
	add: function(title, content){
		this.titles.push(title);
		this.contents.push(content);
		this.hoverSet.add(title);
		this.selectionSet.add(title);	
		this.selectionSet.select(title);
	},
	remove: function(title){},
	removeAll: function(){
		this.hoverSet.removeAll();
		this.selectionSet.removeAll();
	},
	openByIndex: function(index){this.selectionSet.selectIndex(index)},
	contentOf: function(title){ return this.contents[this.titles.indexOf(title)]}
}

Rico.ContentTransition = Class.create();
Rico.ContentTransition.prototype = Object.extend(new Rico.ContentTransitionBase(),{});

Rico.SlidingPanel = Class.create();
Rico.SlidingPanel.prototype = {
	initialize: function(panel) {
		this.panel = panel;
		this.options = arguments[1] || {};
		this.closed = true;
		this.showing = false
		this.openEffect = this.options.openEffect;
		this.closeEffect = this.options.closeEffect;
		this.animator = new Rico.Effect.Animator();
		Element.makeClipping(this.panel)
	},
	toggle: function () {
		if(!this.showing){
			this.open();
		} else { 
			this.close();
    }
	},
	open: function () {
	  if (this.closed){
	    this.showing = true;
		  Element.show(this.panel);
  		this.options.disabler.disableNative();
    }
		/*this.animator.stop();*/
		this.animator.play(this.openEffect,
		 									{ onFinish:function(){ Element.undoClipping($(this.panel))}.bind(this),
												rate:Rico.Effect.easeIn});
	},
 	close: function () {
		Element.makeClipping(this.panel)
		this.animator.stop();
		this.showing = false;
		this.animator.play(this.closeEffect,
	                     { onFinish:function(){  Element.hide(this.panel); 	
																							this.options.disabler.enableNative()}.bind(this),	
												rate:Rico.Effect.easeOut});
	}
}


//-------------------------------------------
// Example components
//-------------------------------------------

Rico.Accordion = Class.create();
Rico.Accordion.prototype = Object.extend(new Rico.ContentTransitionBase(), {
  initContent: function() { 
		this.selected.style.height = this.options.panelHeight + "px";
	},
  transition: function(p){ 
    if (!this.options.noAnimate)
		  return new Rico.AccordionEffect(this.selected, p, this.options.panelHeight);
    else{
      p.style.height = this.options.panelHeight + "px";
      if (this.selected) Element.hide(this.selected);
  		Element.show(p);
    }
	}
})


Rico.TabbedPanel = Class.create();
Rico.TabbedPanel.prototype = Object.extend(new Rico.ContentTransitionBase(), {
  initContent: function() { 
		if (false && (this.options.panelHeight=='auto' || this.options.panelWidth=='auto')) {
		  // 'auto' is not working yet
		  var maxwi=0, maxht=0;
		  for (var i=0; i<this.contents.length; i++) {
		    var d=Element.getDimensions(this.contents[i]);
		    maxwi=Math.max(maxwi,d.width);
		    maxht=Math.max(maxht,d.height);
		  }
		  //alert('maxwi='+maxwi+' maxht='+maxht);
		  if (this.options.panelWidth=='auto') this.options.panelWidth=maxwi;
		  if (this.options.panelHeight=='auto') this.options.panelHeight=maxht;
		}
	  if (typeof this.options.panelWidth=='number') this.options.panelWidth+="px";
	  if (typeof this.options.panelHeight=='number') this.options.panelHeight+="px";
    if (Rico.Corner) {
      this.options.color='transparent';
      this.options.corners='top';
      for (var i=0; i<this.titles.length; i++)
        if (this.titles[i]) {
          if (this.options.panelHdrWidth) this.titles[i].style.width=this.options.panelHdrWidth;
          Rico.Corner.round(this.titles[i], this.options);
        }
    }
		this.transition(this.selected);
	},
  transition: function(p){ 
    if (this.selected) Element.hide(this.selected);
		Element.show(p);
    if (this.options.panelHeight) p.style.height = this.options.panelHeight;
    if (this.options.panelWidth) p.style.width = this.options.panelWidth;
	}
})


Rico.SlidingPanel.top = function(panel, innerPanel){
	var options = Object.extend({
		disabler: Rico.Controls.defaultDisabler
  }, arguments[2] || {});
	var height = options.height || Element.getDimensions(innerPanel)[1] || innerPanel.offsetHeight;
	var top = options.top || Position.positionedOffset(panel)[1];
	options.openEffect = new Rico.Effect.SizeFromTop(panel, innerPanel, top, height, {baseHeight:height});
	options.closeEffect = new Rico.Effect.SizeFromTop(panel, innerPanel, top, 1, {baseHeight:height});
  panel.style.height = "0px";
	innerPanel.style.top = -height + "px";	
	return new Rico.SlidingPanel(panel, options);
}

Rico.SlidingPanel.bottom = function(panel){
	var options = Object.extend({
		disabler: Rico.Controls.blankDisabler
  }, arguments[1] || {});
	var height = options.height || Element.getDimensions(panel).height;
	var top = Position.positionedOffset(panel)[1];
	options.openEffect = new Rico.Effect.SizeFromBottom(panel, top - height, height);
	options.closeEffect = new Rico.Effect.SizeFromBottom(panel, top, 1);
	return new Rico.SlidingPanel(panel, options); 
}

Rico.includeLoaded('ricoComponents.js'); 