//ζɶԵĶγɣԱΪֵ
Fx.Morph = new Class({

 //̳Fx.CSS
 Extends: Fx.CSS,

 //캯ḲǸĹ캯
 initialize: function(element, options){
  //ǸĹ캯Ϊelement
  this.element = this.subject = $(element);
  /*
  ø̶ͬ÷һҲthis.parent
  1543汾Ѿȫarguments.calleeֱʹthisOpera֧caller
  */
  arguments.callee.parent(options);
 },

 //ֱӸǸͬοFx
 set: function(now){
  //ַͣʾΪCSSѡӵҳҳʽвָĹ
  if (typeof now == 'string') now = this.search(now);
  //ֱÿһʽֵ
  for (var p in now) this.render(this.element, p, now[p], this.options.unit);
  return this;
 },

 //ʽԵĵǰֵ
 compute: function(from, to, delta){
  var now = {};
  //ÿһʽԣFx.CSSͬ
  for (var p in from) now[p] = arguments.callee.parent(from[p], to[p], delta);
  return now;
 },

 //ǸͬοFx
 start: function(properties){
   //鵱ǰЧ״̬ǷЧ
  if (!this.check(properties)) return this;
  //ṩpropertiesΪַָCSSѡҪӵǰҳʽвҸ
  if (typeof properties == 'string') properties = this.search(properties);
  var from = {}, to = {};
  //ÿCSSֵͺֵ
  for (var p in properties){
   var parsed = this.prepare(this.element, p, properties[p]);
   from[p] = parsed.from;
   to[p] = parsed.to;
  }
  //Fxͬ
  return arguments.callee.parent(from, to);
 }

});

//̬ԣelement.setelement.getʵֵģʽ
Element.Properties.morph = {

 //setterFx.Morph
 set: function(options){
  //ȴʱȡû浽Fx.Morphʵ
  var morph = this.retrieve('morph');
  //ڣȡִеЧ
  if (morph) morph.cancel();
  //ɾȥɶΪ¶
  return this.eliminate('morph').store('morph:options', $extend({link: 'cancel'}, options));
 },


 //getterȡFx.Morph
 get: function(options){
  //ṩδ뵱ǰElementFx.Morphʵ
  if (options || !this.retrieve('morph')){
   //ṩδFx.MorphʵĲsetterò
   if (options || !this.retrieve('morph:options')) this.set('morph', options);
   //Fx.Morphʵ
   this.store('morph', new Fx.Morph(this, this.retrieve('morph:options')));
  }
  return this.retrieve('morph');
 }

};

Element.implement({

 //Fx.MorphĿݷʽźﲻֲ֧ãҪֹelemenet.set('tween', options)
 morph: function(props){
  /*
  ʹgetterȡFx.Morphʵstart
  propsΪʽCSSѡ
  */
  this.get('morph').start(props);
  return this;
 }

});

