﻿///<reference path="MicrosoftAjax.debug.js" > 
///<reference path="shared.js" > 
///<reference path="control.js" > 


Type.registerNamespace("SLx");



SLx.BasicDockPanel = function( visual , sizeToContent )
{
    
      
    SLx.BasicDockPanel.initializeBase (this , [visual, sizeToContent ] ); 
} 

SLx.BasicDockPanel.prototype = 
{ 
    
    measure : function SLx$BasicDockPanel$measure (  constrainwidth , constrainheight )        
    { 
        //Five children: //LEFT, TOP, RIGHT, BOTTOM, FILL 
        
        if ( this._isMeasureInvalidated == false && SLx.Application.Current.get_cacheLayout() ) 
        {
        
            Sys.Debug.assert ( this.isCacheValueCloseEnough ( constrainwidth ,  [this._lastWidthMeasure , this._desiredSize.Width ] ) , "not error; possible layout cache issue" ) ; 
            Sys.Debug.assert ( this.isCacheValueCloseEnough ( constrainheight,  [this._lastHeightMeasure , this._desiredSize.Height ] ) , "not error; possible layout cache issue" ) ;
            
            // Sys.Debug.assert (  this._lastWidthMeasure  == constrainwidth || this._lastHeightMeasure == constrainheight , "TODO:remove" ) ;   
        
            Sys.Debug.trace( this.toString () + "cached measure" );  
            return; 
        } 
        this._lastWidthMeasure  = constrainwidth ; 
        this._lastHeightMeasure = constrainheight ;   
        
        
        Sys.Debug.assert ( this._children.get_length()  <= 6); 
        
       
        var width, height;  
        if ( this._sizeToContent ) 
        { 
            width = Number.MAX_VALUE ; 
            height = Number.MAX_VALUE ; 
        }
        else 
        { 
            width =  constrainwidth ; 
            height = constrainheight ; 
        }  
        
        var currentwidth = 0 ; 
        var currentheight =  0 ; 
        var maxheight =  (this._sizeToContent)? 0 : height  ; 
        var maxwidth =  (this._sizeToContent)? 0: width  ; 
        
        
        
        var left = 0 ; 
        var top  = 0 ; 
        var right = 0 ; 
        var bottom = 0 ; 
        var fillItem  = null ; 


        for ( var i = 0 ; i < this._children.get_length() ; i++ ) 
        {   
             var item = this._children.getItem ( i ) ;              
                           
             if ( SLx.VisualTreeHelper.isControl( item ) && Object.getType(item).implementsInterface ( SLx.ILayout )) 
             { 
                var marginWidth = item.get_margin().Left + item.get_margin().Right ; 
                var marginHeight = item.get_margin().Top + item.get_margin().Bottom ; 
                
                
                if ( this._sizeToContent && item.get_sizeToParent () ) 
                {   
                    Sys.Debug.assert ( false ,  "You should not have children set to SizeToParent if Parent is SizeToContent; this used to be an assertion ");                   
                    item.set_sizeToParent (false ); 
                } 
                
                 
                var size = item.get_desiredSize ();
                
                if ( item.getAttachedProperty("Dock" ) == SLx.Dock.Fill ) 
                { 
                     
                    size.Width = Math.min ( size.Width , this.get_width () - ( left + right )); 
                    size.Height = Math.min ( size.Height , this.get_height () - ( top + bottom )) ; 
                } 
                 
             //  if ( item.get_horizontalAlignment() == SLx.HorizontalAlignment.Stretch ) 
                { 
                    availwidth = width -  ( marginWidth + left + right) ;                     
                } 
             //   else 
             //       availwidth = Math.min ( size.Width , width ) ; 
                
             //   if ( item.get_verticalAlignment () == SLx.VerticalAlignment.Stretch ) 
                { 
                    availheight = height -  ( marginHeight + top + bottom ); 
                } 
             //   else 
             //       availheight = Math.min ( height , size.Height ) ; 
                    
                
                item.measure ( availwidth , availheight );                              
                
                size = item.get_desiredSize (); 
                
                switch ( item.getAttachedProperty("Dock") ) 
                { 
                    case SLx.Dock.Left: 
                        left = size.Width + marginWidth ; 
                        currentwidth += left; 
                    break;                     
                    case SLx.Dock.Right: 
                        right = size.Width + marginWidth ; 
                        currentwidth += right; 
                        break ; 
                    case SLx.Dock.Top : 
                        top = size.Height + marginHeight ; 
                        currentheight += top;
                        break; 
                    case SLx.Dock.Bottom: 
                        bottom = size.Height + marginHeight ; 
                        currentheight += bottom;
                        break; 
                   case SLx.Dock.Fill: 
                        Sys.Debug.assert ( this._children.get_length() == (i+1) , "Order matters. Fill should be last child"); 
                        currentwidth +=  size.Width + marginWidth ;
                        currentheight  += ( size.Height + marginHeight) ; 
                        break; 
                   default: 
                        Sys.Debug.assert ( false, "this is not an error, we will assume left, but still you should be explicit about docking"); 
                        left = size.Width + marginWidth ; 
                        currentwidth += left; 
                 }           
                 
                 if ( this._sizeToContent ) 
                 { 
                    currentwidth += size.width ; 
                    currentheight += item.height ;                                                       
                 } 
             }
             else if ( this._sizeToContent ) 
             {  
                currentwidth += item.width ; 
                currentheight += item.height ;                            
             }                                    
        }
        
    
        
         if ( this._sizeToContent ) 
         {
            this._desiredSize.Height  = currentheight  ; 
            this._desiredSize.Width = currentwidth ;              
         }   
         else 
         { 
            this._desiredSize.Height =  this.get_height(); 
            this._desiredSize.Width =  this.get_width () ; 
            
         } 
         this._isMeasureInvalidated = false; 
         Sys.Debug.trace ( "measure StackBasicDockPanel h:" + this._desiredSize.get_height() + ",w:" + this._desiredSize.get_width()) ;           
    }, 
    
    
    
    arrange : function SLx$BasicDockPanel$arrange ( left, top, width , height ) 
    { 
    
        
        Sys.Debug.assert ( this._isMeasureInvalidated == false ); 
        var moved =   (  this._visualElement["Canvas.Left"]   != left || this._visualElement["Canvas.Top"] != top ) ; 
        var sized =  ( this._visualElement["width"] != width  || this._visualElement["height"] != height  ); 
        
        
        if ( this._isArrangeInvalidated  == false && moved && sized && SLx.Application.Current.get_cacheLayout()) 
        { 
            Sys.Debug.trace( this.toString () + " cached arrange" ); 
            return; 
        }
         
        this._visualElement["Canvas.Left"] = left; 
        this._visualElement["Canvas.Top"] = top ; 
        this._visualElement.width = width ; 
        this._visualElement.height = height ; 
       
       
         
         /* 
        this._visualElement.width = this.get_desiredSize().Width ; 
        this._visualElement.height = this.get_desiredSize().Height ; 
        */
        
        
        var currentleft = 0 ; 
        var currenttop  = 0 ; 
        
        var left, top, right, bottom ; 
        left = 0;  top = 0 ; 
        bottom =   this._visualElement.height; 
        right =  this._visualElement.width; 
        
        for ( var i = 0 ; i < this._children.get_length () ; i++ ) 
        {   
             var item = this._children.getItem(i);              
             if ( SLx.VisualTreeHelper.isControl( item ) && Object.getType(item).implementsInterface ( SLx.ILayout )) 
             { 
                var size = item.get_desiredSize () ;      
                var margin = item.get_margin();    
                    
                var dock = item.getAttachedProperty("Dock"); 
                var alignmentoffset = SLx.VisualTreeHelper.GetAlignment ( item , this , 
                    true , true );
                
                 var marginWidth = margin.Left + margin.Right ; 
                var marginHeight = margin.Top + margin.Bottom ; 
                     
                
                
                switch ( dock ) 
                { 
                    case SLx.Dock.Left: 
                        left = left + ( size.Width + marginWidth ) ;                         
                        currentleft = 0 ;                 
                        currenttop = top ;                                   
                    break;                     
                    case SLx.Dock.Right:                                                                           
                        currentleft = right - size.Width;
                        right = right - ( size.Width + marginWidth); 
                        break ; 
                    case SLx.Dock.Top : 
                        currentleft = left; 
                        currenttop = top ; 
                        top = top + size.Height + marginHeight ; 
                         break; 
                    case SLx.Dock.Bottom: 
                        currentleft = left; 
                        currenttop = bottom - (size.Height + marginHeight );                         
                         break; 
                    case SLx.Dock.Fill: 
                        currentleft = left; 
                        currenttop = top ; 
                                                 
                         break; 
                   default: 
                        Sys.Debug.assert ( false, "this is not an error, we will assume left, but still you should be explicit about docking"); 
                        left = size.Width + marginWidth ;                         
                 }           
                 
                // TODO is there a better way to do margins?? Right now they add up..
                item.arrange ( alignmentoffset.left + currentleft + margin.Left - margin.Right , 
                               alignmentoffset.top  + currenttop + margin.Top - margin.Bottom,  
                               size.get_width(), size.get_height ()) ;                 
                                    
            }
            else 
            {  
                Sys.Debug.assert(false, "TODO"); 
                 
                SLx.LayoutHelper.Arrange ( item, currentleft, currenttop ) ;                 
                if ( this._orientation == SLx.Orientation.Horizontal ) 
                { 
                    currentleft += item.width ;                      
                } 
                else if ( this._orientation == SLx.Orientation.Vertical ) 
                { 
                     currenttop += item.height ; 
                }
            }             
        }        
        
        if ( this.get_clipToBounds () ) 
        { 
            this.set_clipToBounds (true); 
        } 

        this._isArrangeInvalidated = false ;        
    },
    
  
  
    toString : function  () 
    { 
        return this._uniqueSystemId.toString ()  + "    " + Object.getTypeName(this) + "    " + this._id ; 
    }

} 


SLx.BasicDockPanel.registerClass ( 'SLx.BasicDockPanel', SLx.Panel , SLx.ILayout ); 