﻿///<reference path="MicrosoftAjax.debug.js" > 
///<reference path="shared.js" > 
///<reference path="control.js" > 


SLx.ControlFactory.ContentPresenter = function () 
{ 
    var template = SLx.Application.Current.get_resources().findName ( SLx.Constants.ContentPresenter); 
    if ( template  != "" ) 
    {     
        var ContentPresenter= new SLx.ContentPresenter ( null,  template , SLx.ContentPresenter.DefaultTemplate );          
        return ContentPresenter ; 
        
    } 
    Sys.Debug.assert( false , "this should not fail");     
    return null ; 
} 


SLx.ContentPresenter = function ( visual , xamlTemplate , templateParts )
{ 

    this._child = null ; 
    this._contentChangedListeners = [] ; 
     
     this._contentHAlign = SLx.HorizontalAlignment.Left; 
     this._contentVAlign = SLx.VerticalAlignment.Top; 
     
    if ( typeof(visual)  == "string" ) 
    { 
        visual = SLx.Application.Current.createText ( visual ); 
    } 
    
    Sys.Debug.assert ( visual != null , "Content Control wraps a visual and has no template" ) ; 
    Sys.Debug.assert ( xamlTemplate == null || xamlTemplate == "" , "Content Control wraps a visual and has no template" ) ; 
    Sys.Debug.assert ( templateParts == null , "Content Control wraps a visual and has no template" ) ; 
    
    SLx.ContentPresenter.initializeBase (this , [ visual , xamlTemplate , templateParts ] ); 
    
    /* Removed because it is OK for CP to wrap a Visual 
    if ( this._content== null ) 
    { 
        if ( SLx.VisualTreeHelper.isCanvas ( this._visualElement ) )         
        { 
            Sys.Debug.assert ( this._visualElement.Children.Count == 1 ) 
                this._content = this._visualElement.Children.GetItem(0); 
        } 
    } */ 
    
}, 

SLx.ContentPresenter.DefaultTemplate = [  ]; 

SLx.ContentPresenter.prototype = 
{   


    measure: function ( width , height ) 
    { 
    
        if ( this._isMeasureInvalidated == false && SLx.Application.Current.get_cacheLayout() ) 
        { 
            Sys.Debug.assert ( this.isCacheValueCloseEnough ( width ,  [this._lastWidthMeasure , this._desiredSize.Width ] ) , "not error; possible layout cache issue" ) ; 
            Sys.Debug.assert ( this.isCacheValueCloseEnough ( height,  [this._lastHeightMeasure , this._desiredSize.Height ] ) , "not error; possible layout cache issue" ) ;
           Sys.Debug.trace ( this.toString () + "  cached measure"); 
           return  ;  
        } 
        this._lastWidthMeasure  = width ; 
        this._lastHeightMeasure = height ;   
         
        var dock = this.getAttachedProperty("Dock"); 
        
        if ( dock != null ) 
        { 
            if ( dock == SLx.Dock.Fill || dock == SLx.Dock.Left || dock == SLx.Dock.Right ) 
            { 
                this._verticalAlignment = SLx.VerticalAlignment.Stretch ;                 
            } 
            if ( dock == SLx.Dock.Fill  || dock == SLx.Dock.Top || dock == SLx.Dock.Bottom )
            { 
                this._horizontalAlignment = SLx.HorizontalAlignment.Stretch ;                 
            } 
        } 
        
        
        if ( this._sizeToParent ) 
        {             
            if ( this._horizontalAlignment != SLx.HorizontalAlignment.Stretch ) 
            { 
                this._desiredSize.Width = this.get_width()  ; 
            } 
            else 
            { 
                Sys.Debug.assert( ( width <= ( Number.MAX_VALUE - 2048)) ||SLx.Warning.SingleMeasureOption , "stretching on panel that sizes to content" ) ; 
                this._desiredSize.Width = width  ; 
            }
            
            if ( this._verticalAlignment != SLx.VerticalAlignment.Stretch ) 
            {             
                this._desiredSize.Height  = this.get_height()  ; 
            } 
            else 
            { 
                Sys.Debug.assert( width <= ( Number.MAX_VALUE - 2048) || SLx.Warning.SingleMeasureOption  , "stretching on panel that sizes to content") ; 
                this._desiredSize.Height = height; 
            }                            
        } 
        else if ( this._sizeToContent ) 
        {
            if ( this._content != null ) 
            { 
                this._content.measure ( width, height ); 
                size = this._content.get_desiredSize();    
                
                this._desiredSize.Width = size.Width ; 
                this._desiredSize.Height = size.Height ; 
                             
            } 
            else 
            { 
                if ( this._visualElement.Children.Count > 0 ) 
                { 
                    var item = this._visualElement.Children.GetItem(0); 
                    if ( item.toString () == "TextBlock" ) 
                    {
                       this._desiredSize.Width = item.actualWidth ; 
                       this._desiredSize.Height = item.actualHeight  ;
                    }
                    else 
                    { 
                        this._desiredSize.Width = item.width ; 
                        this._desiredSize.Height= item.Height ; 
                    }                      
                }
                else 
                { 
                    this._desiredSize.Width  = this.get_width () ; 
                    this._desiredSize.Height  = this.get_height () ;  
                }                 
            }         
        } 
        else 
        {         
            this._desiredSize.Width  = this.get_width () ; 
            this._desiredSize.Height  = this.get_height () ;             
        }    
        
        // We measure content becasue we will try to arrange it .. 
        // It is RISKY to measure with new  desiredSize... ..
        // 
        if ( this._content != null && !this._sizeToContent ) 
        { 
            this._content.measure ( this._desiredSize.Width, this._desiredSize.Height );  
        }      
        
        this._isMeasureInvalidated = false ;                
    }, 
    
    set_width : function ( value ) 
    { 
        var oldvalue = this._visualElement.width ; 
        this._visualElement.width = value ;
        if ( oldvalue != value ) 
            this.invalidateLayout();
    }, 
    
    invalidateLayout : function () 
    {
        if (  this._supressInvalidateLayout  ) 
        return ; 
        
        
        this._isMeasureInvalidated = true ; 
        this._isArrangeInvalidated = true ;         
        SLx.Application.Current.get_layoutManager().invalidate ( this );         
        
        if ( this._content != null ) 
        { 
            this._content.invalidateLayout (); 
        }         
        this._fireInvalidateLayout () ; 
    }, 
    
     
    get_width : function () 
    { 
         return this._visualElement.width;     
    }, 
    
    set_height : function ( value ) 
    {   
        var oldvalue =  this._visualElement.height ; 
        this._visualElement.height = value;
        
        if ( oldvalue != value ) 
            this.invalidateLayout();
    }, 
        
    get_height : function () 
    { 
        return this._visualElement.height ; 
    },
    
    set_content : function ( value ) 
    { 
        this._child = null ; 
        if ( value == null ) 
        { 
            this._content = null ;             
            return ; 
        } 
       
        if ( SLx.VisualTreeHelper.isControl ( value )) 
        { 
            this._content = value ;               
            this._setvisual ( value.get_visual() ) ; 
        } 
        else 
        {                         
            this.set_visual ( value );             
        } 
        
        for ( var i = 0 ; i < this._contentChangedListeners.length; i++ ) 
        { 
            this._contentChangedListeners[i] ( this ); 
        } 
         
        this.invalidateLayout(); 
    }, 
    
    
    get_content : function ( ) 
    { 
     //    Sys.Debug.assert( false , "This is OK, assert just to make syre this is what you wanted ");         
        return this._content; 
    }, 
    
    
    get_hasContent : function () 
    { 
        return this._content != null ; 
    }, 
    

    _setvisual : function ( value ) 
    { 
        Sys.Debug.assert ( this._visualElement.Children.Count <= 1 || SLx.Warning.SingleContentModel ); 
        
        this._visualElement.Children.Clear() ;         
        var ok = SLx.VisualTreeHelper.reParent ( value, this._visualElement ); 
    } , 
    
    
    add_contentChanged : function ( callback ) 
    { 
        Array.add ( this._contentChangedListeners , callback ); 
    },  
    
    remove_contentChanged : function ( callback ) 
    { 
        Array.remove ( this._contentChangedListeners , callback ); 
        
    }, 
    
    set_visual : function ( value  ) 
    { 
        if ( this._content != null ) 
        { 
            Sys.Debug.assert ( false || SLx.Warning.ContentReplacesVisual , "This is OK, assert just to make sure this is what you wanted"); 
            this._content = null ; 
        }
        
        if ( typeof(value) == "string" ) 
        { 
            value = SLx.Application.Current.createText ( value ); 
        } 
        
        this._setvisual ( value ); 
       
        
    },
    
    arrange : function (left, top, width, height ) 
    {        
        var moved =   (  this._visualElement["Canvas.Left"]   != left || this._visualElement["Canvas.Top"] != top ) ; 
        var sized =  ( this._visualElement["width"] != width  || this._visualElement["height"] != height  ); 
        
        
         Sys.Debug.assert ( sized == false || SLx.Warning.ArrangeResizes , "Does this imply a relationship is missing?" ); 
        if ( this._isArrangeInvalidated  || sized || moved )
        { 
            Sys.Debug.assert ( this._isMeasureInvalidated == false || SLx.Warning.MatchMeasureArrange , "potential arrange/measure disconnect"  ) ; 
            this._visualElement["Canvas.Left"] = left ;
            this._visualElement["Canvas.Top"]  = top; 
            this._visualElement["width"] = width ; 
            this._visualElement["height"] = height  ; 
                        
            if ( this._content != null &&  SLx.VisualTreeHelper.NeedsAlignment( this._content ) ) 
            {
                var verAlignment = this._content.get_verticalAlignment(); 
                var horAlignment = this._content.get_horizontalAlignment (); 
                
                var childsize = this._content.get_desiredSize (); 
                var top = 0 ; 
                if ( horAlignment == SLx.HorizontalAlignment.Center ) 
                { 
                    left = ( this.get_width() - childsize.Width )/2 ;                  
                } 
                else if ( horAlignment == SLx.HorizontalAlignment.Right ) 
                    left =  this.get_width() - childsize.Width  ; 
                else 
                    left = 0 ; 
                    
                if ( verAlignment == SLx.VerticalAlignment.Center ) 
                { 
                    top = ( this.get_height() - childsize.Height )/2 ;                  
                } 
                else if ( verAlignment == SLx.VerticalAlignment.Right ) 
                    top=   (this.get_height() - childsize.Height )  ; 
                else 
                    top = 0 ; 
                    
                this._content.arrange ( left, top, childsize.Width , childsize.Height ); 
            }
            else 
            { 
                SLx.VisualTreeHelper.alignVisual  ( this._visualElement , width, height, this._contentHAlign, this._contentVAlign ) ;                   
            }                         
        }
        else 
        { 
            Sys.Debug.trace ( this.toString() + " cached arrange" ); 
        }  
        this._isArrangeInvalidated = false ;          
    },

    set_contentHorizontalAlignment : function ( value ) 
    { 
        this._contentHAlign = value ; 
    } , 
    
    set_contentVerticalAlignment : function ( value ) 
    { 
        this._contentVAlign = value ; 
    }, 

    get_containedSize  : function  ( ) 
    { 
        if  ( this._content != null ) 
            return this._content.get_desiredSize () ; 
        else if ( this._visualElement != null && this._visualElement.toString()== "Canvas" && 
            this._visualElement.Children.Count > 0 ) 
        { 
            var item = this._visualElement.Children.GetItem(0); 
            return new SLx.Size ( item.width , item.Height ); 
        }
        Sys.Debug.assert ( false , "Content presenter should be wrapping some thing "); 
        return new Size ( 0, 0);  
    } ,      
    
    toString : function  () 
    { 
        return this._uniqueSystemId.toString ()  + "    " + Object.getTypeName(this) + "    " + this._id ; 
    }
}  


SLx.ContentPresenter.registerClass('SLx.ContentPresenter', SLx.Control ); 
