﻿///<reference path="MicrosoftAjax.debug.js" > 
///<reference path="shared.js" > 
///<reference path="control.js" > 

//STEP 1: Replace Expander w/ your controls' name 
//STEP  2: Move Constants.Expander to shared.js 
//STEP 3: Modify your DefaultTemplate so it matches 
//STEP 4: Update manifest.xaml ... 
//STEP 5:  Add this JS file as a reference in default.html  (or your entry point) 


SLx.ControlFactory.Expander = function () 
{ 
    var template = SLx.Application.Current.get_resources().findName ( SLx.Constants.Expander); 
    if ( template  != "" ) 
    {     
        var Expander= new SLx.Expander ( null,  template , SLx.Expander.DefaultTemplate );          
        return Expander ; 
        
    } 
    Sys.Debug.assert( false , "this should not fail");     
    return null ; 
} 


SLx.Expander = function ( visual , xamlTemplate , templateParts )
{    
    this._panel = null  ; 
    this._content = null ; 
    this._toggleHeader = null ; 
    
    SLx.Expander.initializeBase (this , [ visual , xamlTemplate , templateParts ] );   
    
    Sys.Debug.assert ( this._panel != null ); 
    Sys.Debug.assert ( this._content != null ); 
    Sys.Debug.assert ( this._toggleHeader != null ); 
    
    this._content.add_contentChanged ( $delegate ( this, this._onContentChanged ) ); 
    this._content.add_layoutInvalidated ( $delegate ( this, this._onContentLayoutChanged )) ; 
    
    this._toggleHeader.add_Checked ( $delegate ( this, this._onHeaderChecked )) ; 
    this._toggleHeader.add_unChecked ( $delegate ( this, this._onHeaderChecked )) ; 
    
    
    
    this._panel.get_children().add ( this._toggleHeader); 
    this._panel.get_children().add ( this._content );     
    this._content.set_logicalParent ( this._panel ) ; 
    this._toggleHeader.set_logicalParent ( this._panel ); 
    this._panel.invalidateLayout(); 
    this._panel.set_clipToBounds(true); 
    this._collapsedListeners = [] ; 
    this._expandedListeners = [] ; 
    
    
}, 


SLx.Expander.prototype = 
{   
    _onHeaderChecked : function ( sender, args ) 
    { 
        
        this._isMeasureInvalidated = true ; 
        this._isArrangeInvalidated = true; 
      //   this.updateLayout();               
        var isChecked = this._toggleHeader.get_isChecked ()
        this._content.set_visible (  isChecked ) ;         
        this._notifyChange ( isChecked ) ;          
        this.invalidateLayout(); 
               
    }, 
    
    _onContentChanged : function ( sender, args ) 
    { 
    }, 
    
    _onContentLayoutChanged : function ( sender, args ) 
    { 
    } , 
    
    _notifyChange : function ( isChecked ) 
    { 
        var events = null ; 
        if ( isChecked ) 
            events = this._expandedListeners; 
         else 
            events = this._collapsedListeners; 
            
        for ( var i = 0 ; i < events.length ; i++ ) 
        { 
            events[i] ( this, null ) ; 
        }     
    }, 
    
	get_isExpanded : function () 
	{ 
	    return this._toggleHeader.get_isChecked (); 
	}, 
	
	set_isExpanded : function ( value ) 
	{ 	    
	    var oldvalue = this._toggleHeader.get_isChecked (); 
	    if  ( oldvalue != value ) 
	    { 
	        this._toggleHeader.set_isChecked ( value ); 
	        
	    } 
	},
	
	add_Expanded : function ( callback ) 
	{ 
	    Array.add ( this._expandedListeners , callback ); 
	}, 
	
	remove_Expanded : function ( callback ) 
	{ 
	    Array.remove ( this._expandedListeners , callback ) ; 
	},  
	
	add_Collapsed : function ( callback ) 
	{ 
	    Array.add ( this._collapsedListeners, callback ) ; 
	} , 
	remove_Collapsed : function ( callback ) 
	{   
	    Array.remove ( this._collapsedListeners, callback ); 
	}, 
	
	measure : function ( width , height ) 
	{ 	    
	    this._panel.measure () ; 
	   
	    var toggleSize = this._toggleHeader.get_desiredSize(); 
	    var contentSize = this._content.get_desiredSize(); 	  
	    
	    this._desiredSize.Width = Math.max ( toggleSize.Width, contentSize.Width );    
	    if ( this.get_isExpanded ()) 
	    { 	        	             	        
	        this._desiredSize.Height =  toggleSize.Height + contentSize.Height ; 
	    } 	    
	    else 
	    { 
	        this._desiredSize.Height = toggleSize.Height ; 
	    } 
	    
	    this._isMeasureInvalidate = false; 
	},
	
	arrange : function   ( left, top, width , height ) 
	{ 
	    
	    this._panel.arrange ( left, top, width, height ); 
        
        this._isArrangeInvalidated = false; 
	} , 

    invalidateLayout : function ( ) 
    { 
        if ( ! this._supressInvalidateLayout ) 
        { 
            this._isMeasureInvalidated = true ; 
            this._isArrangeInvalidated = true ;         
            SLx.Application.Current.get_layoutManager().invalidate ( this );         
            this._panel.invalidateLayout (); 
            this._fireInvalidateLayout () ; 
        } 
    }, 
    
    
	
    _bindParts : function SLx$Expander$_bindParts ( templateParts ) 
    {    
       var tag ;                          
         for ( var i = 0 ; i < templateParts .length ; i++ ) 
        { 
            var item = templateParts[i];              
              var element; 
                if ( this._visualElement != null ) 
                    element = this._visualElement.findName ( item.name ) ; 
                
                if ( element == null )  
                    element = SLx.Application.Current.get_host().content.findName ( item.name ) ;  
                
                if ( element != null && element.Tag != "" ) 
                { 
                    tag = eval ( "({" + element.Tag + "})" ) ; 
                } 
                else 
                    tag = null ; 
                            
            if ( item.type == "element" ) 
            { 
                this[item.ref] = element ;                             
            } 
            else if  ( item.type == "BasicDockPanel" || item.type == "StackPanel" ) 
            { 
                
                if ( item.type == "StackPanel" ) 
                {
                    var panel = new SLx.StackPanel ( element , true ); 
                } 
                else 
                    var panel = new SLx.BasicDockPanel ( element , false ); 
                        
                this[item.ref] = panel ; 
                               
            } 
            else if ( item.type  == "Checkbox" ) 
            { 
                //TODO: how to pass these parameters in..?  
                 var check = new SLx.CheckBox ( element , null, 
                [ {name : "ExpanderToggle"  , ref : "_visualElement", type : "element" },
                  {name : "PART_ExpanderToggle_Content"   , ref : "_content", type : "ContentPresenter" }]);               
                  this[item.ref] = check ;                                                              
            }            
            else if ( item.type == "ContentPresenter") 
            { 
                var cp = new SLx.ContentPresenter ( element ) ;                                 
                this[item.ref] = cp ;                                
            }
            else 
            { 
                Sys.Debug.assert(false, "we skipped a type"); 
            }                   
        }                  
    } , 



    toString : function  () 
    { 
        return this._uniqueSystemId.toString ()  + "    " + Object.getTypeName(this) + "    " + this._id ; 
    }
   
}  


SLx.Expander.registerClass('SLx.Expander', SLx.Control ); 


SLx.Expander.DefaultTemplate = [ 
{ name: "Expander" , ref: "_visualElement", type: "element"  } , 
{ name: "Expander" , ref: "_panel", type: "StackPanel" , instantiate:true   } , 
{ name: "ExpanderToggle" , ref: "_toggleHeader", type: "Checkbox" , instantiate:true   } , 
{ name: "PART_ContentSite" , ref: "_content", type: "ContentPresenter" }  
]; 




