var AccordionDLConfig={
    speed:'normal',
    statusClass:{
        open:'open',
        opening:'opening',
        close:'close',
        closing:'closing'
    }
}

function AccordionDT( DT, objDI, objDL ){
    var _self=this;
    var _DT=DT;
    var _objDI=objDI;
    var _objDL=objDL;
    this.getElement=function(){ return _DT; }
    _DT.style.cursor = 'pointer';
    $(_DT).bind('click',function(){ _objDL.open( _objDI.getIndex() ); });
}

function AccordionDD( DD, objDI, objDL ){
    var _self=this;
    var _DD=DD;
    var _objDI=objDI;
    var _objDL=objDL;
    $.registerPlugin( _DD, 'accordionDD', this );
    this.open=function(bool){
        if( bool ) {
            $(_DD).slideDown(AccordionDLConfig.speed, function(){  
                _objDI.setStatus(AccordionDLConfig.statusClass.open);
            });

            var parentDD = _DD.parentNode;
            while( (parentDD.tagName != 'DD') && (parentDD = parentDD.parentNode) );
            if( parentDD && parentDD.plugin && parentDD.plugin.accordionDD )
                parentDD.plugin.accordionDD.open(true);
        } else {
            $(_DD).slideUp(AccordionDLConfig.speed, function(){
                _objDI.setStatus(AccordionDLConfig.statusClass.close);
            });
        }
    }
    this.getElement=function(){ return _DD; }
}

function AccordionDI( DT, DD, objDL, index ){
    var _self=this;
    var _objDT=new AccordionDT(DT, _self, objDL);
    var _objDD=new AccordionDD(DD, _self, objDL);
    var _objDL=objDL;
    var _index=index;
    this.open=function(bool){
        _self.setStatus( bool ? AccordionDLConfig.statusClass.opening : AccordionDLConfig.statusClass.closing );
        _objDD.open(bool);
    }
    this.getIndex=function(){return _index;}
    this.getDT=function(){return _objDT.getElement();}
    this.getDD=function(){return _objDD.getElement();}
    this.setStatus=function( status ){
        $(_objDT.getElement()).replaceClass( AccordionDLConfig.statusClass, status );
        $(_objDD.getElement()).replaceClass( AccordionDLConfig.statusClass, status );
    }
}

function AccordionDL( DL ){
    var _self=this;
    var _DL=typeof(DL)=='string'?$(DL)[0]:DL;
    var _dis=[];
    var _currentIndex=0;
    this.open=function(index){
        if( _currentIndex == index ) index = -1;
        for(var i=0; i < _dis.length; i++ ) _dis[i].open(i==index);
        _currentIndex = index;
    }
    this.close=function(){ _self.open(-1); }
    this.openById=function(ancora){
        for(var i=0; i < _dis.length; i++ ) {
            if( _dis[i].getDT().id == ancora ){
                _self.open(i);
                return;
            }
        }
        _self.close();
    }
    var dts=$(_DL).children('dt'), dds=$(_DL).children('dd');
    for(var i=0; i < dts.length; i++ )
        _dis.push(new AccordionDI(dts[i], dds[i], _self, i));
    _self.openById($.anchor());

}

jQuery.fn.accordionDL=function(){
    return this.each(
        function(index,elem){
            if( elem.tagName == 'DL' ) {
                $.registerPlugin(elem,'accordionDL',new AccordionDL(elem));
            }
        }
    );
}