window.onload = function(){

    var $s = $$._template({

        _init : $$._default( $$._superConstructor( function(){
        })),
        
        _helloWorld : $$._template({
            
            _initHelloWorld : $$._default( $$._constructor( function(){
                this._jsObject();
                this._templateObject();
            })),
            
            _jsObject : $$._private( function(){
            
                var jsObject  = function(){ // constructor
                    var name        = 'обычный JavaScript объект'; // private
                    this._sayMyName = function(){ // public
                        jsObject._say( 'Привет! я ' + name );
                    };
                    this._sayMyName();
                };

                jsObject._say = function( message ){ // static
                    alert( message )  
                }

                document.getElementById( 'create_js_obj' ).onclick = function(){
                    new jsObject();
                }
                
            }),
            
            _templateObject : $$._private( function(){
            
                var templateObject  = $$._template({
                
                    name  : $$._private( '_template.js объект' ),
                    
                    _init : $$._default( $$._constructor( function(){
                        this._sayMyName();
                    })),
                    
                    _sayMyName : $$._public( function(){
                        this._say('Привет! я ' + this.name );
                    }),
                    
                    _say : $$._static( function( message ){
                        alert( message );
                    })
                    
                });
                
                document.getElementById( 'create_template_obj' ).onclick = function(){
                    new templateObject();
                };
                
            })
            
        }),
        
        _testConstructors : $$._public( $$._template( {
        
            _initConstructorsTest : $$._default( $$._constructor( function(){

                var constructors = $$._template({

                    log : $$._public( 
                        document.getElementById('constructor_log')
                    ),
                    
                    // вызыв: constructors._init1();
                    _init1 : $$._constructor( function(){ 
                        this._alert('constructors._init1');
                        this.sub._initSub1();
                    }),
                   
                   // вызов: constructors();
                    _init2 : $$._default( $$._constructor( function(){ 
                        this._alert('constructors._init2');                     
                        this.sub();                       
                    })),

                    // вызов: constructors._initSuper();
                    _initSuper : $$._superConstructor( function(){
                        this._alert('constructors._initSuper');
                    }),                      
                    
                    _alert : $$._public( function( c ){
                        this.log.innerHTML += 'конструктор ' + c + ' сработал<br/>' ;
                    }),
                    
                    sub : $$._public( $$._template({
                    
                        // вызов: this.sub._initSub1();
                        _initSub1 : $$._constructor(function(){
                            this.parent._alert('constructors.sub._initSub1')
                        }),
                        
                        // вызов: this.sub();
                        _initSub2 : $$._default( $$._constructor(function(){
                            this.parent._alert('constructors.sub._initSub2');
                        })),      

                        // вызовется сам собой в constructors._initSuper
                        _initSuper : $$._constructor(function(){
                            this.parent._alert('constructors.sub._initSuper')
                        })                        
                        
                    }))
                    
                })
                
                var a = constructors._init1(),
                    b = constructors(),
                    c = constructors._initSuper(); 
            
            }))
            
            
        })),
        
        _testAccessModificators : $$._public( $$._template( {

            _initTest : $$._default( $$._constructor( function(){
            
                var modificators = $$._template({
                
                    publicVariable    : $$._public( 'Я public переменная' ),
                    privateVariable   : $$._private( 'Я private переменная' ),
                    staticVariable    : $$._static( 'Я static переменная' ),
                    protectedVariable : $$._protected( 'Я protected переменная' ),
                    
                    _initTest : $$._default($$._constructor(function(){
                        this._testVars();
                        this._testVarsStatic();              
                        this.childTpl._initChild();
                    })),
                    
                    _testVars : $$._public(function(){
                        tplLog('<b>Мы находимся в testObj._testVars</b>', this, 'this');                             
                    }),
                    
                    _testVarsStatic : $$._static(function(){
                        tplLog('<b>Мы находимся в testObj._testVarsStatic</b>', this, 'this');                           
                    }),                    
                    
                    childTpl : $$._private( $$._template({
                        _initChild : $$._constructor(function(){
                            this._testVars();                         
                        }),
                        _testVars : $$._public(function(){
                            tplLog('<b>Мы находимся в testObj.childTpl._testVars</b>', this.parent, 'this.parent');                       
                        })
                    }))
                    
                });
                
                // функция проверки доступности переменных
                var tplLog = function(title, obj, objStr ){
                    var logVars = [ 
                            'publicVariable', 
                            'privateVariable', 
                            'staticVariable', 
                            'protectedVariable'
                        ],
                        log     = document.getElementById( 'modificators_log' );
                    log.innerHTML +=  '<br/><b>' + title + '</b><br/>';
                    $$._each(logVars, function(n ,v ){
                        var isFunc = ( typeof obj[v] === 'function' ),
                            value  = isFunc? obj[v]() : obj[v],
                            type   = ( (value != undefined) && isFunc)? '()' : '';
                        log.innerHTML += objStr + '.' + v + type +' == ' + value + '<br/>';
                    })
                }                
                
                tplLog('<b>До создания экземпляра modificators</b>', modificators, 'modificators');
                var testObj = new modificators();             
                tplLog('<b>После создания объекта testObj</b>', testObj, 'testObj');
                
            }))
            
        })),
        
        _extending : $$._public( $$._template( {
            
            _init : $$._default( $$._constructor( function(){
            
                var extendTemplate = $$._template({
                    name : $$._public('Дима'),
                    
                    _init : $$._default( $$._superConstructor( function(){
                        this._sayMyName();                     
                    })),
                    
                    _sayMyName : $$._public( function(){
                        alert( 'Меня зовут ' + this.name );
                    })
                    
                });           
                
                document.getElementById('create_Petia').onclick = function(){

                    extendTemplate = extendTemplate._extend({
                        name : $$._public('Петя')
                     });       

                    new extendTemplate();
                };     
                
                document.getElementById('create_Vasia').onclick = function(){
                
                    extendTemplate = extendTemplate._extend({
                        createName : $$._public( $$._template({
                            _init : $$._constructor( function(){
                                this.parent.name('Вася');
                            })  
                        }))
                    });       
                    
                    new extendTemplate();
                };
                

                document.getElementById('create_undefined').onclick = function(){

                    extendTemplate = extendTemplate._extend({
                            name       : $$._public( undefined ),
                            createName : $$._public( undefined )
                    });  

                    new extendTemplate();
                };  
                
            }))
            
        })),
        
        _nesting : $$._public( $$._template ( {
            
            _initNesting : $$._default( $$._constructor( function(){
            
                var objL1 = $$._template({
                
                    name : $$._public ('шаблон L1'),
                    
                    log  : $$._public ( document.getElementById('nesting_log') ),
                    
                    _initL1 : $$._default( $$._constructor ( function(){
                        this._sayMyName( this.name );
                        new this.objL2();
                    })),
                    
                    _sayMyName : $$._protected( function( name ){
                        this.log.innerHTML += 'Привет! я ' + name + '<br/>';
                    }),
                    
                    objL2 : $$._public( $$._template({
                    
                        name : $$._public ('шаблон L2'), 
                        
                        _initL2 : $$._default( $$._constructor ( function(){
                            this.parent._sayMyName( this.name + ', мой отец - ' + this.parent.name() );
                            new this.objL3();
                        })),
                        
                        objL3 : $$._public( $$._template({
                        
                            name : $$._public ('шаблон L3'), 
                            
                            _initL3 : $$._default( $$._constructor ( function(){
                                this.parent.parent._sayMyName( this.name + ', мой отец - ' + this.parent.name() );
                            }))
                            
                        }))                        
                        
                    }))
                    
                });

                document.getElementById('create_nesting_object').onclick = function(){
                    new objL1();
                }
                
                return;
                
                var objTpl = $$._template({
                
                    age : $$._public( 0 ),
                    
                    name : $$._public(''),
                    
                    _init : $$._default( $$._constructor( function(name, age){
                        this.name = name;
                        this.age = age;
                    }))
                    
                });             
                
                var sort = $$._template({
                    
                    sortArray : $$._private([]),
                    
                    _compare : $$._static( function(a , b ){
                        return ( a.age() >= b.age() );
                    }),
                    
                    _init : $$._default( $$._constructor( function( sortArray ){
                        this.sortArray = sortArray;
                        this._processSorting();
                        this._alertResults();
                    })),
                    
                    _processSorting : $$._private( function(){
                        var sorted = true,
                            self   = this,
                            len    = (self.sortArray.length-1);
                        for (var i = 0; i<len; i++){
                            if (self._compare( self.sortArray[i], self.sortArray[i+1]) != true ){
                                var buf = self.sortArray[i];
                                self.sortArray[i] = self.sortArray[i+1];
                                self.sortArray[i+1] = buf;
                                sorted = false;
                            }
                        }
                        if (! sorted) self._processSorting();
                    }),
                    
                    _alertResults : $$._private( function(){
                        var result = '';
                        $$._each(this.sortArray, function(n,v){
                            result += 'name: '+v.name()+' age: '+v.age()+'\n';
                        });
                        alert( result );
                    })
                });
                
                new sort([
                    objTpl('Вася', 20),
                    objTpl('Петя', 2),
                    objTpl('Даша', 50),
                    objTpl('Лена', 21),
                    objTpl('Оля', 70)                  
                ]);
                

                
            }))
            
        }))
    });
    new $s();
};
