﻿Edo.ApiDocument = function(){    
    Edo.ApiDocument.superclass.constructor.call(this);
}
Edo.ApiDocument.extend(Edo.containers.Box, {
    width: '100%',
    height: '100%',
    _setTpl: function(value){    
        var sf = this;
        if(typeof value == 'string'){            
            Edo.util.Ajax.request({
                url: value,
                async: false,
                type: 'get',
                nocache: false,
                onSuccess: function(text){                
                    sf.tpl = new Edo.util.Template(text);                
                }
            });
        }
    },
    load: function(url){
        if(!url) return;                
        this.mask();
        Edo.util.Ajax.request({
            url: url,
            type: 'get',            
            nocache: false,
            onSuccess: this.onLoad.bind(this)    
        });
    },
    onLoad: function(text){
        var obj = Edo.util.XmlToJson(text);
        this.classMap = {};
        this.toApiTree(obj.namespace, false);        
        
        obj.namespace.expanded = true;                                
        controlTree.data.load([obj.namespace]);
        this.fireEvent('apiready', {
            type: 'apiready',
            source: this
        });
        
        this.unmask();
    },
    toApiTree: function(obj, expand){
        if(!obj.mode) obj.mode = 'namespace';        //这个属性后续会被覆盖掉
        
        var cs = [];
        
        var ns = obj.namespace;
        var cls = obj['class'];
        
        if(ns && !Edo.isArray(ns)) ns = [ns];
        if(cls && !Edo.isArray(cls)) cls = [cls];
            
        if(ns){
            ns.each(function(o){
                o.mode = 'namespace';
                this.toApiTree(o, expand);
                cs.add(o);                                
            }, this);                        
        }
        
        if(cls){
            cls.each(function(o){
                o.mode = 'class';              
                this.toApiTree(o);                
                cs.add(o);                
            }, this);                   
        }
        
        delete obj.namespace;
        delete obj['class'];                
        
        if(obj.mode == 'class'){
        
            if(obj.events) obj.events = obj.events.event;
            if(obj.properties) obj.properties = obj.properties.property;
            if(obj.functions) obj.functions = obj.functions['function'];
            
            if(obj.events && !Edo.isArray(obj.events)) obj.events = [obj.events];
            if(obj.properties && !Edo.isArray(obj.properties)) obj.properties = [obj.properties];
            if(obj.functions && !Edo.isArray(obj.functions)) obj.functions = [obj.functions];
            
            if(obj.events) {
                obj.events.each(function(o){
                    if(o.properties) o.properties = o.properties.property;
                    if(o.properties && !Edo.isArray(o.properties)) o.properties = [o.properties];
                    if(!o.properties) o.properties = [];
                    
                    for(var i=o.properties.length-1; i>=0; i--){
                        var p = o.properties[i];
                        if(p.name == 'type' || p.name == 'source'){
                            o.properties.removeAt(i);
                        }
                    }
                    //附加上两个property
                    o.properties.insert(0, {
                        type: 'String',
                        name: 'type',
                        description: '事件类型名'
                    });
                    o.properties.insert(1, {
                        type: 'Object',
                        name: 'source',
                        description: '事件源对象'
                    });
                    
                });                
            }
            
            if(obj.functions) {
                obj.functions.each(function(o){
                    if(o.params) o.params = o.params.param;
                    if(o.params && !Edo.isArray(o.params)) o.params = [o.params];                                        
                });                
            }                        
        }
        
        if(cs.length>0) obj.children = cs;
        
        if(obj.children){
            obj.expanded = expand;
        }
        
        obj.icon = obj.mode;
        if(obj.single) obj.icon = 'singleton';
        
        var ns = obj.name.split('.');
        obj.shortname = ns[ns.length-1];
        
        ns.remove(obj.shortname);        
        obj.namespace = ns.join('.');
        
        this.classMap[obj.name] = obj;
        
    },
    getClass: function(name){
        return this.classMap[name];
    },
    showClass: function(name, fixId){              
        var api = this;  
        var cls = this.getClass(name);
        var bar = Edo.getCmp("_"+name);
        ns = name.split('.');
        if(!bar){
            var ns = name.split('.');
            bar = tbar.addChild({
                id: "_"+name,
                name: name,
                type: 'button',
                arrowMode: 'close',
                onarrowclick: function(e){
                    var id =name+'page';                                                    
                    var classPage = Edo.getCmp(id);
                    classPage.destroy();
                                        
                    var index = tbar.selectedIndex;                                        
                    var child = tbar.getChildAt(index);                    
                    if(!child){
                        child = tbar.getChildAt(index-1);
                    }
                    if(child){
                        tbar.set('selectedItem', child);                  
                    }
                },
                text: ns[ns.length-1],
                icon: cls.single ? 'singleton' : 'class'
            });
        }    
        tbar.set('selectedItem', bar);
        
        //alert(fix)
        setTimeout(function(){            
            var fixEl = document.getElementById(fixId);
            if(fixEl){        
                var scrollEl = Edo.util.Dom.findParent(fixEl, 'classview');
                Edo.util.Dom.scrollIntoView(fixEl, scrollEl);
            }
        }, 100);                
    },    
    selectClass: function(name){    
        var record = controlTree.data.find({name: name}, true);         
        if(!record) return;
        controlTree.data.expand(record,true);                
        
        controlTree.select(record);
    },
    init: function(){    
        var welcome = this.tpl.call('welcome');        
    
        var apiDoc = this;     
        var tabItems = [
            {type: 'button', text: 'API Home', icon: 'home', data: 'pages/dashboard.xml'}
        ];
        this.set('children', [
            {
                type: 'ct', width: '100%', height: 35, layout: 'horizontal', verticalAlign: 'middle', style: 'background:#1e4176',
                children:[
                    {type: 'html',width: 400,height: 30,style: 'FONT: 16px tahoma, arial, sans-serif;color: white;line-height:30px;padding-left:15px;',html: 'EdoJS API Document'},
                    {type: 'space',width: '100%'},
                    //{type: 'html',width: 80,height: 25, html: '<a href="http://www.edojs.com" target="_blank"><img src="res/edojs.gif" width="100%" height="100%"/></a>'},
                    {type: 'label', text: '切换皮肤', style: 'color:white;'},
                    {type: 'combo', data: this.skins,
                        selectedIndex: this.skinIndex,width: 100, readOnly: true,
                        onselectionchange: function(e){
                            var skinLink = document.getElementById('edoskin');
                            if(skinLink) Edo.removeNode(skinLink);
                            var src = e.selectedItem.src;
                            
                            if(src){
                                var link = document.createElement('link');
                                link.id = 'edoskin',
                                link.href = src;
                                link.rel = 'stylesheet';
                                link.type = "text/css";
                                document.body.appendChild(link);                                                            
                            }
                        }
                    },
                    {type: 'space',width: 5}
                ]
            },
            {
                type: 'box',width: '100%',height: '100%',border: [1,0,0,0],
                children:[
                    {
                        type: 'ct',layout: 'horizontal',width: '100%',
                        children: [
                            {type: 'ct', width: 250, layout: 'horizontal',
                                children:[
                                    {id: 'searchBtn',type: 'search',width: '100%', changeAction: 'keydown'},
                                    {type: 'ct', cls: 'e-toolbar', layout: 'horizontal', style: 'background:white', horizontalGap: 0,
                                        children: [
                                            {id: 'collapseallBtn',type: 'button', icon: 'collapseall', tips: '收缩所有节点'},
                                            {type: 'split'},
                                            {id: 'expandallBtn',type: 'button', icon: 'expandall', tips: '展开所有节点'}
                                        ]
                                    }
                                ]
                            },                            
                            {type: 'space',width: '100%'}
//                            ,                            
//                            {
//                                type: 'button',enableToggle: true,pressed: true,icon: 'btn-inherited',
//                                ontoggle: function(e){
//                                    Edo.util.Dom.toggleClass(document.body, 'hide-inherited');
//                                }
//                            }
                        ]
                    },
                    {
                        type: 'ct',width: '100%',height: '100%',layout: 'horizontal',enableSplit: true,
                        children:[
                            {
                                id: 'doc_tree',type: 'box',width: 250,height: '100%',padding:0,border: 0,splitRegion: 'west',splitPlace: 'after', collapseProperty: 'width',enableCollapse: true,
                                children:[
                                    {
                                        id: 'controlTree',type: 'tree',autoColumns: true,horizontalLine: false,verticalLine: false,verticalScrollPolicy: 'auto',headerVisible: true,width: '100%',height: '100%',
                                        onselectionchange: function(e){                                        
                                            var o = e.selected;
                                            if(o.mode == 'class'){                                                
                                                apiDoc.showClass(o.name);
                                            }                                            
                                        },
                                        columns: [
                                            {
                                                headerText: '组件类',
                                                width: 100,
                                                dataIndex: 'name',
                                                renderer: function(v, r){
                                                    var ns = v.split('.');
                                                    return ns[ns.length - 1];
                                                }
                                            }
                                        ]
                                    }
                                ]
                            },
                            {
                                type: 'box',width: '100%',height: '100%',verticalGap: 0,padding: 0,border: 0,
                                children:[
                                    {
                                        type: 'tabbar',id: 'tbar',width: '100%',horizontalGap: 2,selectedIndex: 0,
                                        children: tabItems,
                                        onselectionchange: function(e){
                                            var index = e.source.selectedIndex;
                                            var item = e.source.getChildAt(index);
                                            
                                            if(item.name){
                                                var record = controlTree.data.find({name: item.name}, true);                                               
                                                if(record){                                                   
                                                    //创建并选中与tab对应的div组件(如果没有则创建)
                                                    var id = record.name+'page';
                                                    
//                                                    record.width = viewCt.realWidth;
//                                                    alert(viewCt.realWidth+":"+viewCt.minWidth);
                                                    var classPage = Edo.getCmp(id);
                                                    if(!classPage){
                                                        classPage = viewCt.addChild({
                                                            id: id,
                                                            type: 'div',
                                                            verticalScrollPolicy: 'auto',
                                                            width: '100%',
                                                            height: '100%',
                                                            html: apiDoc.tpl.run(record)
                                                        });
                                                    }
                                                }
                                            }
                                            viewCt.set('selectedIndex', index);
                                            
                                            setTimeout(function(){
                                                location.hash = item.name;
                                            }, 100);
                                        }
                                    },
                                    {
                                        type: 'box',border: [0,1,1,1],layout: 'viewstack',style: 'background-color:white;',id: 'viewCt',minWidth: 300,width: '100%',height: '100%',
                                        children:[
                                            {
                                                id: 'index', type: 'ct',width: '100%', height:'100%',layout:'horizontal',verticalScrollPolicy: 'auto',                                                
                                                children: [
                                                    {type:'space',width: 20},
                                                    {
                                                        type: 'ct',width: '100%', height: '100%',
                                                        children: [ 
                                                            {type:'space',height: 15},
                                                            {id: 'searchAll', type: 'search', width: '100%', changeAction:'keydown'},
                                                            {type:'space',height: 10},
                                                            {
                                                                id: 'resultList',
                                                                type: 'dataview',
                                                                width: '100%',
                                                                height: '100%',
                                                                overCls: 'overitem',
                                                                selectedCls: 'selecteditem',            
                                                                cls: 'ctt',
//    verticalScrollPolicy: 'auto',
//    horizontalScrollPolicy: 'auto',                                                                
                                                                //itemTpl: '<div id="<%=this.itemId %>" class="<%=this.itemCls %>"><%=this.index %><%=this.item.text %>,<%=this.item.value %></div>',
                                                                itemTpl: '<div class="apiItem"><a class="<%=this.item.iconType%>" href="javascript:api.showClass(\'<%=this.item._className%>\',\'<%=this.item.name%>\')"><%=this.item.name%></a><div><%=this.item.description%></div></div>',
                                                                emptyText: '<span style="color:#888;">您可以输入搜索关键字，比如“destory”...</span><span style="color:#888;padding-top:5px;display:block;">搜索结果最多显示前50条</span>'
                                                            }
                                                        ]
                                                    },
                                                    {type: 'label',width: '250',height: 'auto',text: welcome}
                                                ]
                                            }                                            
                                        ]   
                                    }
                                    
                                ]
                            }
                        ]
                    }         
                ]
            }
        ]);            
        
        Edo.ApiDocument.superclass.init.call(this);       
        
        
        var key = '';
        searchBtn.on('trigger', function(e){            
            key = this.text.toLowerCase();       
            if(key == "") {
                if(this.clearVisible){
                    this.set('clearVisible', false);
                    controlTree.data.clearFilter();
                }
                return;
            }                    
            
            this.set('clearVisible', true);
            
            controlTree.data.filter(function(node){            
                if(node.name.toLowerCase().indexOf(key) != -1) return true;
                return false;
            });
            controlTree.data.expand(controlTree.data, true);
        });
        searchBtn.on('keydown', function(e){        
            if(e.keyCode == 13){            
                this.fireEvent('trigger');
            }
        });
        searchBtn.on('cleartrigger', function(e){
            this.set('clearVisible', false);
            //this.set('text', '');
            
            key = '';
            controlTree.data.clearFilter();
        });
        
        collapseallBtn.on('click', function(e){
            controlTree.data.collapse(controlTree.data, true);
        });
        expandallBtn.on('click', function(e){
            controlTree.data.expand(controlTree.data, true);
        });         
        ////////////////////////
        
        var allKey = '';
        function search(text){
            allKey = text.toLowerCase();       
            
            var data = [];
            
            var classMap = apiDoc.classMap;
            for(var name in classMap){
                var cls = classMap[name];
                if(!cls.description) cls.description = "";
                if( cls.name.toLowerCase().indexOf(allKey) != -1
                    || cls.description.toLowerCase().indexOf(allKey) != -1){
                    cls.iconType = 'icon-cls';
                    if(cls.single) cls.iconType = 'icon-static';
                    cls._className = cls.name;
                    data.add(cls);
                }
                if(cls.properties){
                    cls.properties.each(function(o){
                        o.iconType = 'icon-prop';
                        o._className = cls.name;
                        if(!o.description) o.description = "";
                        
                        if(o.name.toLowerCase().indexOf(allKey) != -1
                            || o.description.toLowerCase().indexOf(allKey) != -1){                            
                            data.add(o);
                        }
                    });
                }
                if(cls.functions){
                    cls.functions.each(function(o){
                        o.iconType = 'icon-method';
                        o._className = cls.name;
                        if(!o.description) o.description = "";
                        
                        if(o.name.toLowerCase().indexOf(allKey) != -1
                            || o.description.toLowerCase().indexOf(allKey) != -1){                            
                            data.add(o);
                        }
                    });
                }
                if(cls.events){
                    cls.events.each(function(o){
                        o.iconType = 'icon-event';
                        o._className = cls.name;
                        if(!o.description) o.description = "";
                        
                        if(o.name.toLowerCase().indexOf(allKey) != -1
                            || o.description.toLowerCase().indexOf(allKey) != -1){                            
                            data.add(o);
                        }
                    });
                }
            }
            data = data.splice(0, 50);
            
            resultList.data.load(data);
        }
        searchAll.on('trigger', function(e){
            search(this.text);
            this.set('clearVisible', true);                        
        });
        searchAll.on('keydown', function(e){
            if(e.keyCode == 13){
                search(this.text);
                this.set('clearVisible', true);
            }
        });
        searchAll.on('cleartrigger', function(e){
            this.set('clearVisible', false);
            //this.set('text', '');
            
            allKey = '';
            resultList.data.load([]);
        });        
    },
    getBaseClassName: function(cls){
        if(typeof cls == 'string') cls = this.classMap[cls];
        return cls.extend;
    },
    getInherited: function(cls, propertyName, hash){
        //获得当前类
        if(typeof cls == 'string') cls = this.classMap[cls];
        var first = false;
        if(!hash) {
            hash = {};
            first = true;
        }
        var list = cls[propertyName];
        if(list && list.length>0){
            for(var i=0,l=list.length; i<l; i++){
                var li = list[i];            
                li.exception = false;
                
                var o = hash[li.name];  
                if(o){                  //如果子类也定义了属性
                    li = Edo.apply({}, o, li);
                    
                }
                if(first) hash[li.name] = li;   //只显示当前类新定义和重新定义的
                //hash[li.name] = li;   //全部显示
                
                li.definedby = cls.name;         
                
                if(first) li.exception = true;       //如果是首个子类重定义的属性, 则例外显示
            }
        }
        if(!cls.name || cls.name == 'undefined') return [];
        var baseCls = this.classMap[cls.extend];
        if(baseCls) this.getInherited(baseCls, propertyName, hash);//从基类继承属性和方法
        
        //将cls.names上的属性, 设置上去
//        var names = cls.names;
//        for(var name in names){
//            var o = names[name];
//            var prop = hash[o.name];
//            
//        }
        
        if(first){
            var arr = [];
            for(var name in hash){
                arr[arr.length] = hash[name];
            }
            arr.sortByFn(function(pre, next){   
                return next.name > pre.name;
            });
            
            arr.reverse();                        
            
            return arr;
        }
    },
    getInheritedProperties: function(cls){        
        return this.getInherited(cls, 'properties');
    },
    getInheritedFunctions: function(cls){
        return this.getInherited(cls, 'functions');
    },
    getInheritedEvents: function(cls){
        return this.getInherited(cls, 'events');
    }
});
Edo.ApiDocument.regType('api');
