appdb.views = {};
appdb.View = appdb.DefineClass("appdb.views.View",function(o){
        this._mediator = null;
        this.subviews = [];
        this.dom = null;
        this.id = "";
        this.idPostfix = "";
        this.subscribe = null;
        this.publish = null;
        this.unsubscribe = null;
        this.unsubscribeAll = null;
        this.clearObserver = null;
        this.parent = null;
		this.clearSubviews = function(){
			var i, len;
			if(this.subviews && this.subviews.length>0){
				len = this.subviews.length;
				for(i=0; i<len; i+=1){
					this.subviews[i].destroy();
					this.subviews[i] = null;
				}
				this.subviews = [];
			}
		};
		this.destroy = function(){
			this.clearSubviews();
			this.reset();
			this.unsubscribeAll();
		};
		this.reset = function(){
			this.clearSubviews();
			$(this.dom).empty();
		};
		this.setContainer = function(cont){
			this.dom = cont;
			return this;
		};
        var _constructor = function(){
			o = o || {};
			if(typeof o.container === "string"){
				this.id = o.container;
				if($(this.id).length>0){
					this.dom = $($(this.id)[0]);
				}
			}else{
				this.id = $(o.container).attr("id");
				this.dom = $(o.container);
			}
            this._mediator = new appdb.utils.ObserverMediator(this);
            this.subscribe = this._mediator.subscribe;
            this.publish = this._mediator.publish;
            this.unsubscribe = this._mediator.unsubscribe;
            this.unsubscribeAll = this._mediator.unsubscribeAll;
            this.clearObserver = this._mediator.clearAll;
			this.parent = o.parent || null;
        };
        _constructor.call(this);
    });

appdb.views.DelayedDisplay = function(o){
    var _dom = null, _delay = 200, _visible = false,_useDefault=false;
    var _init = function(){
        if(typeof o === "string"){
            _dom = $(o);
            return ;
        }else{
			o = o || {};
			_dom = $(o.selector);
			_delay = o.delay || 200;
			_useDefault = o.usedefault || false;
		}
		if(_useDefault){
			$(_dom).append('<img src="/images/ajax-loader-small.gif" alt="" width="12px" height="12px" style="padding:0px;margin:0px;vertical-align: top"  /><span style="font-style: italic;font-size: 12px;vertical-align: super;padding:0px;margin:0px;">Loading...</span>');
		}
    };
    _init();
   return {
       show : function(){
           _visible = true;
            setTimeout(function(){
                if(_visible===true){
                    $(_dom).css("visibility","visible");
                }
            },_delay);
       },
       hide : function(){
            _visible = false;
            $(_dom).css("visibility","hidden");
       }
    };
};
appdb.views.ListViewMode  = function(o){
   var _container = "",_id="",_list = null,_mode = 1, _dom = null ;
   this.reset = function(){
       $(_dom).find("a").unbind("click");
       $(_dom).empty();
   };
   this.render = function(){
        var that = this;
        this.reset();
        var img1 = $("<a href='#'></a>").click(function(){that.setViewMode(1);}).
            append("<img id='"+_id+"gridviewimg' border='0' title='Grid view' alt='grid view' src='images/gridview_s.png' ></img>").css("padding","5px"),
        img2 = $("<a href='#'></a>").click(function(){that.setViewMode(2);}).
            append("<img id='"+_id+"listviewimg' border='0' title='List view' alt='list view' src='images/listview.png' ></img>");
        $(_dom).empty().append(img1).append(img2);
        this.setViewMode(_mode);
   };
   this.setViewMode = function(m){
        if (m == 2) {
            $(_list).addClass("itemlist");
			$(_list).removeClass("itemgrid");
			$(_list).attr("classname","itemlist");
            $("#"+_id+"gridviewimg").attr("src","images/gridview.png");
            $("#"+_id+"listviewimg").attr("src","images/listview_s.png");
        } else {
            $(_list).addClass("itemgrid");
			$(_list).removeClass("itemlist");
            $(_list).attr("classname","itemgrid");
            $("#"+_id+"gridviewimg").attr("src","images/gridview_s.png");
            $("#"+_id+"listviewimg").attr("src","images/listview.png");
        }
        _mode = m;
   };
   var _init = function(){
       _container = o.container || "";
       _dom = $(_container);
       _list = $(o.list);
       _id = $(_container).attr("id");
   };
   _init();
};
appdb.views.PagerPane = appdb.ExtendClass(appdb.View, "appdb.views.PagerPane",function(o){
        this._createPageItem = function(pg,page){
            var res = {};
            if(isNaN(page)){
                if(page==="prev"){
                    res["type"] = "previous";
                    res["iscurrent"] = ((pg.pageNumber===0))?true:false;
                }else if(page==="next"){
                    res["type"] = "next";
                    res["iscurrent"] = ((pg.pageNumber+1)===pg.pageCount)?true:false;
                }else{
                    res["type"] = "sep";
                    res["iscurrent"] = false;
                }
                res["index"] = -1;
            }else{
                res["type"] = "page";
                res["index"] = page;
                res["iscurrent"] = ((pg.pageNumber+1)===page)?true:false;
            }
            return res;
        };
        this._createPager = function(pg,sides,center){
            var res = [];
            if(pg.pageCount===1){
                return res;
            }
            if(pg.pageCount<=((sides*2)+center)){
                res = this._createFullPager(pg);
            }else{
                res = this._createSplitPager(pg,sides,center);
            }
            return res;
        };
        this._createFullPager = function(pg){
            var i,len = pg.pageCount,res = [],pgitem = this._createPageItem;
            res[res.length] = pgitem(pg,"prev");
            for(i=1; i<=len; i+=1){
                res[res.length] = pgitem(pg,i);
            }
            res[res.length] = pgitem(pg,"next");
            return res;
        };
        this._createSplitPager = function(pg,sides,center){
            sides = sides || 2;
            center = center || 2;
            var i, len = pg.pageCount, pgnum = pg.pageNumber,res=[], left = sides, right=sides,
                sepleft=false, sepright=false, centerLen =0, _pgitem = this._createPageItem;
            res[res.length] = _pgitem(pg,"prev");
            if((pgnum)<(sides+center-1)){
                    left = (sides*2)+center;
                    sepright=true;
                    center = 0;
                }else if((pgnum+sides+center-1)>=len){
                    right=(sides*2)+center;
                    sepleft = true;
                    center = 0;
                }else{
                    sepright = sepleft = true;
                }
                centerLen = (pgnum+Math.floor(center/2)+1);
                //left side buttons
                for(i=1;i<=left;i+=1){
                        res[res.length]= _pgitem(pg, i);
                }
                //left seperator
                if(sepleft===true){
                    res[res.length] = _pgitem(pg,"sep");
                }
                //center buttons
                if(center>0){
                    for (i=(pgnum-Math.floor(center/2)+1); i<=centerLen; i+=1) {
                        res[res.length] = _pgitem(pg,i);
                    }
                }
                //right seperator
                if(sepright===true){
                    res[res.length] = _pgitem(pg,"sep");
                }
                //right side buttons
                for (i=(len-right+1);i<=len;i+=1) {
                    res[res.length] = _pgitem(pg,i);
                }
                res[res.length] = _pgitem(pg,"next");
                return res;
        };
        this.reset = function(){
            var pl = dijit.byId(this.id+this.idPostfix);
            if(pl){
                pl.destroyRecursive(false);
            }
            if(this._pagerModel){
                this._pagerModel.unsubscribeAll(this);
            }
        };
        this.render = function(pger){
          var bt, ui, i=0, bts = this._createPager(pger,2,2), len = bts.length, layout = null,_this=this;
          this.reset();
          if(bts.length===0){
              return;
          }
           layout = new dijit.layout.LayoutContainer({
               id: this.id+this.idPostfix,
               style: "margin-left: auto; margin-right: auto; display:block; width:90% !important;   overflow-x:auto;"
           });
           while(len--){
                bt = bts[i++];
                switch(bt.type){
                    case "previous":
                        ui = new dijit.form.Button({
                            label : "<div style='width:20px;'>&lt;</div>",
                            style : "font-family:Arial,sans-serif;font-size:12px;font-weight:400;color:#454545;",
                            disabled : bt.iscurrent,
                            onClick : function(){
                                _this.publish({event:"previous",value:""});
                            }
                        });
                        break;
                    case "next":
                        ui = new dijit.form.Button({
                            label : "<div style='width:20px;'>&gt;</div>",
                            style : "font-family:Arial,sans-serif;font-size:12px;font-weight:400;color:#454545;",
                            disabled : bt.iscurrent,
                            onClick : function(){
                                _this.publish({event:"next",value:""});
                            }
                        });
                        break;
                    case "sep":
                        ui = new dijit.layout.ContentPane({
                            content : "...",
                            style : "display:inline-block;width:20px;font-weight:bold"
                        });
                        break;
                    case "page":
                        ui = new dijit.form.Button({
                            label : "<div style='width:20px'>"+bt.index+"</div>",
                            style : "font-family:Arial,sans-serif;font-size:12px;font-weight:400;color:#454545;padding:2px;",
                            disabled : bt.iscurrent,
                            onClick : (function(p){
                                return function(){
                                    _this.publish({event:"current",value:(p-1)});
                                };
                            })(bt.index)
                        });
                        break;
                }
                layout.addChild(ui);
           }
           layout.placeAt(this.id || $(this.dom)[0]);
        };
        this.destroy = function(){
            this.clearObserver();
            this.reset();
            $(this.id).empty();
        };
    });
appdb.views.Ordering = appdb.ExtendClass(appdb.View, "appdb.views.Ordering", function(o){
        var opt={}, _dstore = null, _this = this;
		this._selected ={value : null , name : null , order : "ASC"};
        this._operations=null;
        var _nameByValue = function(v){
		 var i, items = opt.items || [], len = items.length;
		 for(i=0; i<len; i+=1){
		  if($.isArray(items[i].value)){
			if(items[i].value[0]===v){
			 return items[i].name[0];
			}
		  }else{
			if(items[i].value===v){
			 return items[i].name;
			}
		  }
		 }
		 return null;
        };
		this.getSelected = function(){
			if(this._selected.value===null){
				return null;
			}
			return {"orderby": this._selected.value,"orderbyOp":this._selected.order + ((this._selected.operation)?" "+this._selected.operation:"")};
		};
		this.setSelected = function(value,order){
		 this._selected.value = value || this._selected.value;
		 this._selected.order = order || this._selected.order;
		 this._selected.name = _nameByValue(this._selected.value);
		};
		this.resetSelected = function(){
		 this._selected ={value : opt.selected , name : _nameByValue(opt.selected) , order : "ASC"};
		};
        this._constructor = function(){
            opt = o || {};
            this.id = opt.container;
            this.idPostfix = "orderinglist";
            _dstore = new dojo.data.ItemFileReadStore({
                data: {label:"name",id:"value",items:opt.items}
            });
            this._selected.value = opt.selected;
            if(this._selected.value){
                this._selected.name = _nameByValue(this._selected.value);
            }
        }
        this.reset = function(){
            var pl = dijit.byId(this.id+this.idPostfix);
            if(pl){
                pl.destroyRecursive(false);
            }
        };
        this._setOperations = function(sel){
            var store = new dojo.data.ItemFileReadStore({
                    data: {label:"name",items: [{name:"asc",value:"ASC"},{name:"desc",value:"DESC"}]}
                });
            if(sel && sel.operation){
                store =  new dojo.data.ItemFileReadStore({
                    data: {label:"name",items: [{name:"asc",value:"ASC " + sel.operation},{name:"desc",value:"DESC " + sel.operation}]}
                });
            }
            return store;
        };
        this.render = function(d){
            var layout = null, ui = null;
            this.reset();
			d = d || {};
			this._selected.value = d.orderby || this._selected.value;
			this._selected.order = d.orderbyOp || this._selected.order;
            layout = new dijit.layout.LayoutContainer({
               id: this.id+this.idPostfix,
               style: "margin-left: auto; margin-right: auto; display:block; width:auto !important; max-width:500px;  overflow-x:auto;"
            });
            ui = new dijit.layout.ContentPane({
                content : "Order By",
                style : "display:inline-block;font-weight:bold;vertical-align:middle;"
            });
            layout.addChild(ui);
            ui =new dijit.form.FilteringSelect({
                required : true,
                store: _dstore,
                searchAttr : "name",
                displayedValue : this._selected.name,
                style : "margin-left: 5px; max-width: 110px",
                onChange: function(v){
                    _this._selected.value = opt.items[v].value[0];
                    _this._selected.name = opt.items[v].name[0];
                    if(opt.items[v].operation){
                        _this._selected.operation = opt.items[v].operation[0];
                        _this.publish({event : "order",value:{"orderby": _this._selected.value,"orderbyOp":_this._selected.order + " "+_this._selected.operation}});
                    }else{
                        _this._selected.operation = null;
                        _this.publish({event : "order",value:{"orderby": _this._selected.value,"orderbyOp":_this._selected.order}});
                    }
                    
                }
            });
            layout.addChild(ui);
            ui =   new dijit.form.FilteringSelect({
                store: this._setOperations(this._selected),
                displayedValue : this._selected.order,
                style : "margin-left: 5px; max-width: 70px",
                onChange: (function(_this){
                    return function(v){
                        _this._selected.order = ((v===0)?"ASC":"DESC");
                        if(_this._selected.operation){
                            _this.publish({event : "order",value:{"orderby": _this._selected.value,"orderbyOp":_this._selected.order + " "+_this._selected.operation}});
                        }else{
                            _this.publish({event : "order",value:{"orderby": _this._selected.value,"orderbyOp":_this._selected.order}});
                        }
                        
                    };
                })(this)
            });
            layout.addChild(ui);
            layout.placeAt(this.id/*_container*/);
        };
        this.destroy = function(){
            this.reset();
            this.clearObserver();
        };
        this._constructor();
    });
appdb.views.Filter = appdb.ExtendClass(appdb.View, "appdb.views.Filter", function(o){
        this.opt={},this._field='flt',this._watermark = "Search...",this._width = null,this._isRich = false,this._currentValue="", this.txtbox = null,this.btclear=null;this._domEvents = [],this._isFuzzy=0,this.displayClear=false;
        this._constructor = function(){
            this.opt = o || {};
            if(this.opt.rich){
                this._isRich = (this.opt.rich===false)?false:true;
            }
            if(this.opt.width){
                this._width = this.opt.width;
            }
            if(this.opt.watermark){
                this._watermark = this.opt.watermark;
            }
            if(this.opt.field){
                this._field = this.opt.field;
            }
			if(this.opt.displayClear){
				this.displayClear = true;
			}
        };
        this.reset = function(){
            var de = this._domEvents;
            dojo.forEach(de,dojo.disconnect);
            var pl = dijit.byId(this.id+this.idPostfix);
            if(pl){
                this._domEvents = [];
                pl.destroyRecursive(false);
            }
            if(this.txtbox){
				if ($($(this.txtbox.domNode).find(":input")).attr("data-fixInt") !== undefined) {
					clearInterval($($(this.txtbox.domNode).find(":input")).attr("data-fixInt"));
				}
                this.txtbox.destroyRecursive(false);
                this.txtbox = null;
            }
            if(this.btclear){
                this.btclear.destroyRecursive(false);
                this.btclear = null;
            }
            return this;
        };
        this.setValue = function(v){
            v = v ||{};
            v[this._field] = v[this._field] || "";
            if(this._isRich){
                v.fuzzySearch = v.fuzzySearch || 0;
                this._isFuzzy = v.fuzzySearch;
            }
            this._currentValue = v[this._field];
            if(this.txtbox){
                if (this._currentValue === "") {
                    this.txtbox.attr("value",this._watermark);
                    this.txtbox.attr("style",{"color":"#CCCCCC"});
                }else{
                    this.txtbox.attr("value",this._currentValue);
                }
            }
            this._onValueChange(this._currentValue);
            return this;
        };
        this.getValue = function(){
            return this._currentValue;
        };
        this.isFuzzy = function(b){
            if(typeof b === "boolean"){
                this._isFuzzy = (b)?1:0;
            }
            if(isNaN(this._isFuzzy)){
                this._isFuzzy = 0;
            }
            return this._isFuzzy
        }
        this.setWatermark = function(d){
            if(typeof d === "string"){
                this._watermark = d;
            }else{
                this._watermark = "Search...";
            }
            return this;
        };
        this.getWatermark = function(){
            return this._watermark;
        };
        this._onValueChange = function(v){
            if(this.btclear){
				if($.trim(v)===""){
					this.btclear.set('content','<a href="#" title="Clear filter" style="display:none;" ><img alt="clear filter" src="images/cancelicon.png" style="vertical-align: middle" border="0" /></a>');
				}else{
					this.btclear.set('content','<a href="#" title="Clear filter" ><img alt="clear filter" src="images/cancelicon.png" style="vertical-align: middle" border="0" /></a>');
				}
			}
        };
        this._createQuery = function(v){
            var q={};
            q[this._field] = v || '';
            if(this._isRich){
                q.fuzzySearch=this.isFuzzy();
            }
            q.pageoffset = 0;
            return q;
        };
		this._autoComplete = function(v){
			var app_data = "id name description abstract date year month day tool rating person country middleware vo discipline tag subdiscipline".split(" ");
			var ppl_data = "id firstname lastname name date year month day institute country role gender application vo discipline subdiscipline".split(" ");
			var vo_data2 = "id name description".split(" ");
			var ppl_data2 = "id firstname lastname name date year month day institute gender".split(" ");
			var domain_data2 = "id name".split(" ");
			var country_data2 = "id name isocode".split(" ");
			var app_data2 = "id name description abstract date year month day tool rating".split(" ");

			function concatData(adata, bdata, s) {
				var tmp,i;
				tmp = bdata;
				for(i=0; i<bdata.length; i++) {
					tmp[i] = s+"."+tmp[i];
				}
				return adata.concat(tmp);
			}

			function appAutoComplete(e) {
				var adata = app_data;
				adata = concatData(adata, ppl_data2, "person");
				adata = concatData(adata, domain_data2, "discipline");
				adata = concatData(adata, domain_data2, "subdiscipline");
				adata = concatData(adata, vo_data2, "vo");
				adata = concatData(adata, country_data2, "country");
				autoComplete(e, adata);
			}

			function pplAutoComplete(e) {
				var adata = ppl_data;
				adata = concatData(adata, app_data2, "application");
				adata = concatData(adata, domain_data2, "discipline");
				adata = concatData(adata, domain_data2, "subdiscipline");
				adata = concatData(adata, vo_data2, "vo");
				adata = concatData(adata, country_data2, "country");
				autoComplete(e, adata);
			}

			function vosAutoComplete(e) {
				autoComplete(e);
			}

			function autoComplete(e, adata) {
				var predata = '~ = + - < > <= >= +~ += +< +> +<= +>= -~ -= -< -> -<= ->= "'.split(" ");
				var data = [];
				var i,j, ilen, jlen;
				ilen = adata.length;
				jlen = predata.length;
				for(i=0; i<ilen; i++) {
					data.push(adata[i]);
				}
				for(i=0; i<ilen; i+=1) {
					for(j=0; j<jlen; j+=1) {
						data.push(predata[j]+adata[i]);
					}
				}
				//set an interval to fix ": " -> ":" in none exists,
				//and save it's id in a data attribute
				if ( $(e).attr("data-fixInt") === undefined ) {
					$(e).attr("data-fixInt",setInterval(function() {
						var s1=$(e).val();
						var s2=s1.replace(/: /g,":");
						if (s1!==s2){
							$(e).val(s2);
						}
					}, 1000));
				}
				return $(e).autocomplete(data, {
					multiple: true, 
					multipleSeparator: " ",
					max: data.length,
					scroll: true,
					selectFirst: false,
					formatResult: function(data,pos,n) {
						return data+":";
					}
				});
			}
			var inp = $(this.txtbox.domNode).find(":input");
			v = v || "apps";
			switch(v){
				case "apps":
					appAutoComplete(inp);
					break;
				case "people":
					pplAutoComplete(inp);
					break;
				case "vos":
					vosAutoComplete(inp);
					break;
			}		
		}
        this.render = function(){
            var layout = null,  btsearch = null,bthelp=null, fuzzy = null,_this = this;
            this.reset();
            layout = new dijit.layout.LayoutContainer({
                id : this.id+this.idPostfix,
                style : "white-space: nowrap; margin-left: 0; margin-right: auto"
            });
            this.txtbox = new dijit.form.TextBox({
                id : this.id+this.idPostfix+"simpleFilter",
                value :  this._currentValue || "",
                title : "Keywords search, googlesque syntax applies",
                style : ((this._width!==null)?"width:"+this._width+";":"")
            });
            if (this._currentValue === "" || this._currentValue === this._watermark) {
                    this.txtbox.attr("value",this._watermark);
                    this.txtbox.attr("style",{"color":"#CCCCCC"});
            }
            this._domEvents.push(dojo.connect(this.txtbox, "onFocus", this, function(k) {
                if (_this.txtbox.attr("value") == _this._watermark) {
                        _this.txtbox.attr("value","");
                        _this.txtbox.attr("style",{"color":"inherit"}); 
                }
            },true));
            this._domEvents.push(dojo.connect(this.txtbox, "onBlur", this, function(k) {
                var t = _this.txtbox;
                if (t.attr("value") === "" || t.attr("value") === _this._watermark) {
                        t.attr("value",_this._watermark);
                        t.attr("style",{"color":"#CCCCCC"});
                }
            },true));
            this._domEvents.push(dojo.connect(this.txtbox, "onKeyUp", this, function(e) {
                var v = _this.txtbox.attr("displayedValue"), q , k = (window.event) ? event.keyCode : e.keyCode;
                _this._onValueChange(v);
                if (k == dojo.keys.ENTER) {
                    q = _this._createQuery(v);
                    _this.publish({event:"filter",value : q});
                }
            },true));
            
            this._domEvents.push(dojo.connect(this.txtbox, "onMouseDown", this,function(k) {
                 if (_this.txtbox.attr("value") === _this._watermark) {
                        _this.txtbox.attr("value","");
                        _this.txtbox.attr("style",{"color":"inherit"});
                }
            },true));
            btsearch = new dijit.layout.ContentPane({
                content : '<a href="#" title="Search"><img src="images/search.png" style="vertical-align: middle" border="0" alt="" /></a>',
                style : 'display:inline;padding:2px;'
            });
            this._domEvents.push(dojo.connect(btsearch,"onClick", this, function(){
                var v = _this.txtbox.attr("value"), q;
                if(v===_this._watermark){
                    v = "";
                }
                q = _this._createQuery(v);
                _this.publish({event:"filter",value : q});
            },true));
            layout.addChild(this.txtbox);
            layout.addChild(btsearch);
			if(this._isRich===true || this.displayClear===true){
				this.btclear = new dijit.layout.ContentPane({
                    content : '<a href="#" title="Clear filter" '+((this._currentValue==="" || this._currentValue===this._watermark)?'style="display:none;"':'')+' ><img alt="clear filter" src="images/cancelicon.png" style="vertical-align: middle" border="0" /></a>',
                    style : 'display:inline;'
                });
                this._domEvents.push(dojo.connect(this.btclear,"onClick", this, function(){
                    _this.txtbox.attr("value",_this._watermark);
                    _this.txtbox.attr("style",{"color":"#CCCCCC"});
					var val = {fuzzySearch:_this.isFuzzy(), pageoffset:0};
					val[_this._field]='';
                    _this.publish({event:"filter",value : val} );
                },true));
				layout.addChild(this.btclear);
			}
            if(this._isRich===true){
                bthelp = new dijit.layout.ContentPane({
                    content : '<a href="#" title="Help on filters" onclick="filterHelp(this);"><img alt="help on filters" src="images/question_mark.gif" style="vertical-align: middle" border="0" /></a>',
                    style : 'display:inline;padding:2px;padding-right:5px;'
                });
                fuzzy = new dijit.form.CheckBox({
                    onChange : function(v){
                       _this.isFuzzy(v);
                    },
                    value : "fuzzy",
                    title : "Try to match similar sounding keywords, based on the soundex phonetic algorithm"
                });
                
                fuzzy.attr("checked",this.isFuzzy());
                layout.addChild(bthelp);
                layout.addChild(fuzzy);
                layout.addChild(new dijit.layout.ContentPane({content:"<span title='Try to match similar sounding keywords, based on the soundex phonetic algorithm'>Fuzzy</span>",style:"display:inline;"}));
            }
			//this._autoComplete((this.parent.views._export)?this.parent.views._export.target:"apps");
            layout.placeAt(this.id || $(this.dom)[0]);
            return this;
        };
        this.destroy = function(){
            this.clearObserver();
            this.reset();
        };
        this._constructor();
    });
appdb.views.ExtendedFilter= appdb.ExtendClass(appdb.views.Filter,"appdb.views.ExtendedFilter",function(o){
    this._targets = null, this._height = null, this._selectedTarget = null,this._targetButton=null,this._seperator=null,this._buttonHeight=20;
    this._setSelectedTarget = function(v){
        var change = (this._selectedTarget)?((this._selectedTarget.text!==v.text)?true:false):true;
        this._selectedTarget = v;
        this._targetButton.attr("label","<div style='vertical-align:middle;'  title='"+(v.title || v.text)+"'><img src='"+v.image+"' width='"+this._buttonHeight+"px' alt='' ></img><span style='display:inline-block;vertical-align:top;padding-top:3px;width:115px;'>"+v.text +"</span></div>");
        //this._targetButton.attr("label","<img src='"+v.image+"' alt='' title='"+(v.title || v.text)+"' width='20px'></img>");
        if(change){
			//this._autoComplete(v.value);
            this.publish({event:"target",value:v});
        }
    };
    this.render = function(){
        this.reset();
        if(this._targetButton!==null){
            this._targetButton.destoyRecursive(true);
            this._targetButton = null;
        }
        var layout = null,  inlayout = null,btsearch = null,bthelp=null, fuzzy = null,_this = this;
        this.reset();
        layout = new dijit.layout.LayoutContainer({
            id : this.id+this.idPostfix,
            style : "white-space: nowrap; margin-left: 0; margin-right: auto;padding:0px;display:inline-block;"
        });
        var w = ((this._width!==null)?"width:"+this._width+";":""), h = ((this._height!==null)?"padding-top:"+this._height+";padding-bottom:"+this._height+";":"");
        inlayout = new dijit.layout.LayoutContainer({
			style :"border:#3D3D3D 0px solid;display:inline-block;background-color:white;display:inline-block;border:1px solid grey"
        });
        
        this.txtbox = new dijit.form.TextBox({
            id : this.id+this.idPostfix+"simpleFilter",
            value :  this._currentValue || "",
            title : "Keywords search, googlesque syntax applies",
            style :w+h+"border:none;padding-left:3px;"
        });

        if (this._currentValue === "" || this._currentValue === this._watermark) {
                this.txtbox.attr("value",this._watermark);
                this.txtbox.attr("style",{"color":"#3D3D3D"});
        }
        this._domEvents.push(dojo.connect(this.txtbox, "onFocus", this, function(k) {
            if (_this.txtbox.attr("value") == _this._watermark) {
                    _this.txtbox.attr("value","");
                    _this.txtbox.attr("style",{"color":"inherit"});
            }
        },true));
        this._domEvents.push(dojo.connect(this.txtbox, "onBlur", this, function(k) {
            var t = _this.txtbox;
            if (t.attr("value") === "" || t.attr("value") === _this._watermark) {
                    t.attr("value",_this._watermark);
                    t.attr("style",{"color":"#3D3D3D"});
            }
        },true));
        this._domEvents.push(dojo.connect(this.txtbox, "onKeyUp", this, function(e) {
            var v = _this.txtbox.attr("displayedValue"), q , k = (window.event) ? event.keyCode : e.keyCode;
            _this._onValueChange(v);
            if (k == dojo.keys.ENTER) {
                q = _this._createQuery(v);
                if(_this._selectedTarget!==null){
                    q = {query:q,target:_this._selectedTarget};
                }
                _this.publish({event:"filter",value : q});
            }
        },true));

        this._domEvents.push(dojo.connect(this.txtbox, "onMouseDown", this,function(k) {
             if (_this.txtbox.attr("value") === _this._watermark) {
                    _this.txtbox.attr("value","");
                    _this.txtbox.attr("style",{"color":"inherit"});
            }
        },true));
        btsearch = new dijit.layout.ContentPane({
            content : '<a href="#" title="Search"><img src="images/search.png" style="vertical-align: middle" border="0" alt="" /></a>',
            style : 'display:inline;padding:2px;border:none;'
        });
        this._domEvents.push(dojo.connect(btsearch,"onClick", this, function(){
            var v = _this.txtbox.attr("value"), q;
            if(v===_this._watermark){
                v = "";
            }
            q = _this._createQuery(v);
            if(_this._selectedTarget!==null){
                q = {query:q,target:_this._selectedTarget};
            }
            _this.publish({event:"filter",value : q});
        },true));
        inlayout.addChild(this.txtbox);
        inlayout.addChild(btsearch);

        layout.addChild(inlayout);
        if(this._isRich===true || this.displayClear===true){
            this.btclear = new dijit.layout.ContentPane({
                content : '<a href="#" title="Clear filter" '+((this._currentValue==="" || this._currentValue===this._watermark)?'style="display:none;"':'')+' ><img alt="clear filter" src="images/cancelicon.png" style="vertical-align: middle" border="0" /></a>',
                style : 'display:inline;'
            });
            this._domEvents.push(dojo.connect(this.btclear,"onClick", this, function(){
                _this.txtbox.attr("value",_this._watermark);
                _this.txtbox.attr("style",{"color":"#3D3D3D"});
                var val = {fuzzySearch:_this.isFuzzy(), pageoffset:0};
                val[_this._field]='';
                _this.publish({event:"filter",value : val} );
            },true));
            inlayout.addChild(this.btclear);
        }
        if(this._isRich===true){
            bthelp = new dijit.layout.ContentPane({
                content : '<a href="#" title="Help on filters" onclick="filterHelp(this);"><img alt="help on filters" src="images/question_mark.gif" style="vertical-align: middle" border="0" /></a>',
                style : 'display:inline;padding:2px;padding-right:5px;'
            });
            fuzzy = new dijit.form.CheckBox({
                onChange : function(v){
                   _this.isFuzzy(v);
                },
                value : "fuzzy",
                title : "Try to match similar sounding keywords, based on the soundex phonetic algorithm"
            });

            fuzzy.attr("checked",this.isFuzzy());
            layout.addChild(bthelp);
            layout.addChild(fuzzy);
            layout.addChild(new dijit.layout.ContentPane({content:"<span title='Try to match similar sounding keywords, based on the soundex phonetic algorithm'>Fuzzy</span>",style:"display:inline;"}));
        }
        if(this._targets!==null){
            var menu = new dijit.Menu({
                style: "display:none"
            });
            for(var i in this._targets){
                this._targets[i].index = parseInt(i);
                menu.addChild(new dijit.MenuItem({
                    label : "<div style='margin-left:-20px;vertical-align:middle;'><img src='"+this._targets[i].image+"' width='"+this._buttonHeight+"' alt='' ></img><span style='display:inline-block;vertical-align:top;padding-left:3px;padding-top:3px;'>"+this._targets[i].text +"</span></div>",
                    onClick : (function(_this,v){
                        return function(){
                            _this._setSelectedTarget(v);
                        };
                    })(this,this._targets[i])
                }));
            }
             this._targetButton = new dijit.form.ComboButton({
                label:"",
                dropDown: menu,
                style : "margin:0px;padding:0px;border:#3D3D3D 0px solid;height:"+this._buttonHeight,
                onClick : (function(_this){
                    return function(){
                        var ts = _this._targets, s = _this._selectedTarget, index = 0;
                        if(s===null){
                            return;
                        }
                        if(s.index<ts.length-1){
                            index=s.index+1;
                        }
                        _this._setSelectedTarget(ts[index]);
                    };
                })(this)
            });
            this._setSelectedTarget(this._targets[0]);
            if(this._separator !==null){
                layout.addChild(new dijit.layout.ContentPane({content: this._seperator,style:"display:inline-block;padding:0px;vertical-align:top;"}));
            }
            layout.addChild(this._targetButton);
        }
        layout.placeAt(this.id);
        return this;
    };
    this._constructor = function(){
        if(this.opt.height){
            if(isNaN(this.opt.height)===false){
                if(this.opt.height>0){
                    this._height = Math.round(this.opt.height/2) + "px";
                }
            }
        }
        if(this.opt.buttonHeight){
            if(isNaN(this.opt.buttonHeight)===false){
                if(this.opt.buttonHeight>0){
                    this._buttonHeight = Math.round(this.opt.buttonHeight) + "px";
                }
            }
        }
        if(this.opt.targets){
            this._targets = this.opt.targets;
            if(this.opt.seperator){
                this._seperator = this.opt.seperator;
            }
        }
    };
    this._constructor();
});
appdb.views.ResultTimer = appdb.ExtendClass(appdb.View, "appdb.views.ResultTimer", function(o){
        this.render = function(cnt,msecs){
            var secs = ((msecs)/1000);
            $(this.dom).empty();
            var div = document.createElement("div");
			$(div).css({"font-size":"11px","color":"gray"});
            $(div).append("<span style='white-space: nowrap'>" + cnt + " matches in " + secs + "s</span>");
            $(this.dom).append(div);
        };
        this.appendRender = function(msecs){
            var secs = ((msecs)/1000);
            if ( appdb.config.appenv != "production" ) {
				$(this.dom).append("<span style='white-space: nowrap'><div style='font-size:11px;color:gray'>Rendered in "+secs + " s</div></span>");
            }
        }
    });
appdb.views.Permalink = appdb.ExtendClass(appdb.View, "appdb.views.Permalink", function(o){
        this.datatype = "apps";
		this._permalink = "";
		this._constructor = function(){
            this.container = $("<span></span>");
            this.datatype = o.datatype || "apps";
        };
        /*this.makeQueryString = function(d){
            var res = "";<
            for(var i in d){
                res += i + "=" + encodeURI(d[i])+"&";
            }
            if(res!==""){
                res = res.substring(0,res.length-1);
            }
            return res;
        };*/
        /*this.render = function(d){
           var u,s;
           this.reset();
           if(typeof d === "undefined" || d===null){
               d = {flt:''};
           }else if(typeof d === "string"){
               d = this.makeQueryString(d);
               s = "/"+this.datatype+"?"+d;
               u = appdb.config.endpoint.base+"?p="+appdb.utils.base64.encode(s);
           }else{
               s = {url : "/"+this.datatype, query: d.query,ext:d.ext};
               s = JSON.stringify(s);
               u = appdb.config.endpoint.base+"?p="+appdb.utils.base64.encode(s);
           }
		   if(typeof appdb.config!=="undefined"){
			   appdb.config.permalink = u;
		   }
           if(u.substr(0, 5)==="https"){
               u = "http"+u.slice(5,u.length);
           }
		   $(this.container).empty().append("<a href='"+u+"' target='_blank' title='permalink for this search results'>permalink</a>");
           $(this.dom).append(this.container);
        };*/
		this.render = function(d,pager){
           this.reset();
		   u = appdb.Navigator.createPermalink(d,this.datatype);
		   appdb.Navigator.setPermalink(u);
		   this._permalink = u;
		   $(this.container).empty().append("<a href='"+appdb.config.permalink+"' target='_blank' title='permalink for this search results'>permalink</a>");
           $(this.dom).append(this.container);
        };
		this.getCurrentPermalink = function(){
		 return this._permalink;
		};
        this._constructor();
    });
appdb.views.ListItem = appdb.ExtendClass(appdb.View,"appdb.views.ListItem", function(o){
	this._itemData = null;
	this._constructor = function(){
		this._itemData = o.itemdata || null;
	};
	this._constructor();
});
appdb.views.List = appdb.ExtendClass(appdb.View,"appdb.views.List",function(o){
	this._listtype = null;
	this._listData = [];
	this._nodata = "";
	this.postRender = function(){};
	this._constructor = function(){
		if(typeof o.container === "string"){
			this.id = o.container;
			 if($(this.id).length>0){
				this.dom = $($(this.id)[0]);
			}
		}else{
			this.id = $(o.container).attr("id");
			this.dom = $(o.container);
		}
		this._listtype = o.listtype || appdb.views.ListItem;
		if(o.nodata){
			this._nodata = $(o.nodata);
		}else{
			this._nodata = $(document.createElement("span")).text("Nothing to display")[0];
		}
		if($.isFunction(o.onPostRender)==true){
			this.postRender = o.onPostRender;
		}
	};
	this.setListType = function(v){
		this._listtype = v;
	};
	this.itemSubscriptions = [];
	this.filterItems = function(filter){
		var i, d = this.subviews, len = d.length, res = [];
		if(typeof filter === "function"){
			for(i=0; i<len; i+=1){
				if(filter(d[i])==true){
					res[res.length] = d[i];
				}
			}
			return res;
		}else{
			return d;
		}
	};
	this.onBeforeItemRender = function(){
		return true;
	};
	this.onAfterItemRender = function(){};
	this.onItemAction = function(action,item){};
	this.initItemSubscriptions = function(li){
		var i, len = this.itemSubscriptions.length;
		for(i=0; i<len; i+=1){
			li.subscribe(this.itemSubscriptions[i]);
		}
	};
	this.appendItem = function(d){
		var res = document.createElement("li"), li;
		$(res).addClass("itemcontainer");
		$(this.dom).append(res);
		if(d instanceof this._listtype){
			li = d;
			li.setContainer(res);
		}else{
			li = new this._listtype({container : $(res)[0],itemdata : d});
			li.parent = this;
		}
		li.parent = this;
		if(this.onBeforeItemRender(li)){
			this.initItemSubscriptions(li);
			li.render();
			this.onAfterItemRender(li);
			this.subviews[this.subviews.length] = li;
			return li;
		}
		return null;
	};
	this.render = function(d){
		d = d || this._listData;
		if($.isArray(d) == false) d = [d];
		var len = (d)?((typeof d.length !== "undefined")?d.length:len):0,  f = $(this.dom)[0];
		this.reset();
		if(len===0){
			$(f).append(this._nodata);
		}else{
			for(var i=0; i<len; i+=1){
				this.appendItem(d[i]);
			}
		}
		this.postRender();
	};
});
appdb.views.PeopleListItem = appdb.ExtendClass(appdb.views.ListItem,"appdb.views.PeopleListItem",function(o){
	this.render = function(d){
		this._itemData = d || this._itemData;
		d = this._itemData;
		var doc = document,fullname = d.firstname + " "+d.lastname,a,img,div, span,span1,span2,isos,i,flags="",pimg, ishttps =  Boolean(appdb.config.https) && true,prot;
		isos = d.country.isocode.split("/");
		for(i=0; i<isos.length; i+=1){
			//flags += "<img width='16px' style='padding-right:3px;display:inline;float:left;' src='/images/flags/"+isos[i].toLowerCase()+".png' border='0' />";
			flags += "<img width='16px' src='/images/flags/"+isos[i].toLowerCase()+".png' border='0' />";
		}
		flags = "<span class='personflags' >" + flags + "</span>";
		a = $(doc.createElement("a")).attr("href","#").attr("title",fullname).addClass("itemlink").click((function(_this,data){
			return function(){
				_this.publish({event:"click",value : data});
			};
		})(this,d));
		pimg = d.image;
		if(pimg){
			prot = pimg.substr(4,1);
			if(ishttps===true && prot === ":"){
				pimg = "https" + pimg.substr(4,pimg.length);
			}else if(prot==="https"){
				pimg = "http:" + pimg.substr(5,pimg.length);
			}
		}
		div = doc.createElement("div");
		$(div).addClass("item");
		img = $(doc.createElement("img")).
			attr("src",((pimg)?"people/getimage?req="+encodeURI(d.lastUpdated)+"&id="+d.id: appdb.config.images.person)).addClass("itemimage");
		span = $(doc.createElement("span")).append(fullname).addClass("itemname");
		if(isos.length>1){
			$(span).addClass("flagcount"+isos.length);
		}
		span1 = $("<span></span>").append(unescape(d.role.type)+"<br/>"+(d.institute.substring(0,80))+((d.institute.length>80)?'...':'')).addClass("itemsorttext");
		span2 = $("<span></span>").append(unescape(d.role.type)+"<br/>"+((d.institute)?d.institute+', ':'')+d.country.val()+"<br/>Registered since "+d.registeredOn).addClass("itemlongtext");
		$(a).append(img);
		$(a).append(flags);
		$(a).append(span);
		$(a).append(span1);
		$(a).append(span2);
		$(div).append($(a));
		$(this.dom).append(div);
	};
	this.reset = function(){
		$(this.dom).find("div > a").each(function(index,elem){
			$(this).unbind("click");
		});
		$(this.dom).empty();
	};
});

appdb.views.PeopleList = appdb.ExtendClass(appdb.views.List, "appdb.views.PeopleList", function(o){
	this._constructor = function(){
		this.setListType(appdb.views.PeopleListItem);
		this.itemSubscriptions = [
			{event:"click",callback:function(data){
					if(this.parent && this.parent.views.pager){
						this.publish({event:"itemclick",value : data});
					}else{
						appdb.views.Main.showPerson({id:data.id},{mainTitle : data.firstname + " " + data.lastname,append:true});
					}
			},caller:this}];
			$(this.dom).addClass("peoplelist");
	};
	this._constructor();
});
appdb.views.RelatedContactListItem = appdb.ExtendClass(appdb.views.ListItem,"appdb.views.RelatedContactListItem",function(o){
	this.isSelectable = false;
	this.useToggleButton = false;
	this.customSelectable = undefined;
	this._isSelected = false;
	this.canSetContactPoint = false;
	this._selectToggle = null;
	this.isSelected = function(sel){
		if(this.isSelectable == false){
			return false;
		}
		if(typeof sel !== "undefined" ){
			if(this._isSelected != sel){
				this._isSelected = sel;
			}else{
				return this._isSelected;
			}
		}else{
			return this._isSelected;
		}
		var c = $(this._selectToggle.domNode);
		if(this._isSelected){
			this._selectToggle.attr("checked",true);
			$(this._selectToggle.domNode).attr("title","Click to unselect contact");
			$(c).parent().parent().parent().addClass("selected");
			if(this.useToggleButton==false){
				$(c).before("<span class='selectedtext'>selected</span>");
			}
		}else{
			this._selectToggle.attr("checked",false);
			$(this._selectToggle.domNode).attr("title","Click to select contact");
			$(c).parent().parent().parent().removeClass("selected");
			if(this.useToggleButton==false){
				$(c).parent().find("span:first").remove();
			}
		}
		this.publish({event:"selected",value:this});
		return this._isSelected;
	};
	this.editContactPoint = function(){
		if(this.parent._application==null){
			alert("cannot find application");
		}else{
			if(this.subviews.length>0){
				this.subviews[0].destroy();
				this.subviews[0] = null;
			}
			this.subviews[0] = new appdb.views.ContactPointEditor({container : document.createElement("div"),listitem:this});
			this.subviews[0].render();
		}
	};
	this.renderSelectable = function(){
		if(this.isSelectable){
			var div = $(this.dom).find(".item:last");
			var span3 = document.createElement("span"), check = document.createElement("span");
				$(span3).addClass("researcherCheck");
				if(this.useToggleButton==true){
					$(span3).addClass("togglebutton");
				}
				$(span3).append(check);
				$(div).append(span3);
				if(this._selectToggle){
					this._selectToggle.desctroyRecursive(false);
					this._selectToggle = null;
				}
			if(this.useToggleButton){
				this._selectToggle = new dijit.form.ToggleButton({
					checked: this.isSelected(),
					showLabel : true,
					iconClass : "dijitCheckBoxIcon",
					label : "remove",
					title : "Set for removal",
					onChange: (function(_this){
						return function(v){
							_this.isSelected(v);
							if(v==true){
								this.attr("title",((v==true)?"Un":"")+"set for removal");
							}
						};
					})(this)
				},
				check);
				//$(this.dom).find(".item .researcherCheck .selectedtext").remove();
			}else{
				this._selectToggle = new dijit.form.CheckBox({
					checked: this.isSelected(),
					onChange: (function(_this){
						return function(v){
							_this.isSelected(v);
						};
					})(this)
				},
				check);
			}
		}
	};
	this.hasChanges = function(){
	 var ci = [],len,i;
	 if(this._itemData.isNew && (this._itemData.toRemove==true || this._itemData.toRemoveImplicit==true)===false){
	  return true;
	 }else if((this._itemData.toRemove==true || this._itemData.toRemoveImplicit==true) && (this._itemData.isNew == false)){
	  return true;
	 }else if((this._itemData.toRemove==true || this._itemData.toRemoveImplicit==true) && (this._itemData.isNew == true)){
	  return false;
	 }
	 if(this._itemData.contactItem ){
	  ci = this._itemData.contactItem;
	  if($.isArray(ci)===false){
	   ci = [ci];
	  }
	 }
	 len = ci.length;
	 for(i=0; i<len; i+=1){
	  if(ci[i].isNew || ci[i].toRemove || ci[i].toRemoveImplicit){
	   return true;
	  }
	 }
	 return false;
	};
	this.renderContactPoints = function(){
		var i,  len, d = [] , div = $(this.dom).find(".item:last"), view = document.createElement("div"),  lnk = document.createElement("a"), popupmsg = '';
		if(this._itemData.contactItem){
			if($.isArray(this._itemData.contactItem)==false){
				this._itemData.contactItem = [this._itemData.contactItem];
			}
			d = this._itemData.contactItem;
		}
		len = d.length;

		//VIEW PART
		$(view).addClass("relatedcontactpointview");
		if(d.length>0){
			//Build title
			var cptitlesort , cptitle = "";
			for(i=0; i<len; i+=1){
				cptitle += (d[i].val)?d[i].val():'';
				if(i+1<len){
					cptitle += ", ";
				}
			}
			cptitlesort = cptitle;
			if(cptitlesort.length>20){
				cptitlesort = cptitlesort.slice(0,17) + "...";
			}
			cptitle = $("<span title='"+cptitle+"'>Contact point for " + cptitlesort + "</span>");
			$(view).append(cptitle);
			//build details to show in popup
			var details = "<div class='relatedcontactpointview details' >";
			details += "<span class='title' >" + this._itemData.lastname + " is acting as a contact point for this application and relates with the following entities:</span>";
			var gd = appdb.utils.GroupObjectList(d, "type");
			for(i in gd){
				details += "<div class='contactpoint' ><b>-</b> " +((i.toLowerCase()=='other')?'':i+" : ")  ;
				for(var j=0; j<gd[i].length; j+=1){
					details += (gd[i][j].val)?gd[i][j].val():'';
					if(j+1<gd[i].length){
						details += ", ";
					}
				}
				details += "</div>";
			}
			details += "<div class='contactpointprofile'>Click <a href='#' title='Go to "+this._itemData.firstname + " "+ this._itemData.lastname +" profile' onclick='appdb.views.Main.showPerson({id: "+this._itemData.id+"},{mainTitle: \""+this._itemData.firstname + " "+ this._itemData.lastname+"\"});'>here</a> to see " + this._itemData.firstname + " "+ this._itemData.lastname+" contact details</div>";
			details += "</div>";
			 var detailslink = document.createElement("a");
			 $(detailslink).attr("href","#").attr("title","Click to view contact points").text("details").click((function(__this,msg){
				 return function(){
					 var pu =  new dijit.TooltipDialog({content : msg});
					 setTimeout((function(_this){
						return function(){
							dijit.popup.open({
								parent : $(_this)[0],
								popup: pu,
								around : $(_this)[0],
								orient: {'TL':'BL','TR':'BR'}
							});
						};
					 })(__this),1);
				 };
			 })(detailslink,details));
			 $(view).append(detailslink);
		}
		$(div).append(view);
		//END VIEW PART

		//EDIT PART
		if(this.canSetContactPoint){
			var edit=document.createElement("span"), editlnk = document.createElement("a");
			$(edit).addClass("editcontactpoint");
			$(editlnk).attr("href","#").attr("title",((d.length==0)?"Set":"Edit ")+" " + this._itemData.firstname + " " + this._itemData.lastname + "  expertise").text(((d.length==0)?"Set expertise":"Edit expertise"));
			$(editlnk).click((function(_this){
				return function(){
					_this.editContactPoint();
				}
			})(this));
			$(edit).append(editlnk);
			$(div).append(edit);
		}
		//END EDIT PART
	};
	this.render = function(d){
		this._itemData = d || this._itemData;
		d = this._itemData;
		var doc = document,fullname = d.firstname + " "+d.lastname, a, img, div, span, span1, span2, isos, i, flags="",pimg, ishttps =  Boolean(appdb.config.https) && true, prot;
		isos = d.country.isocode.split("/");
		for(i=0; i<isos.length; i+=1){
			flags += "<img width='16px'  src='/images/flags/"+isos[i].toLowerCase()+".png' border='0' />";
		}
		flags = "<span class='personflags'>" + flags + "</span>";
		a = $(doc.createElement("a")).attr("href","#").attr("title",fullname).addClass("itemlink").click((function(_this,data){
			return function(){
				if(_this.parent.EditMode()){
					if(_this.useToggleButton==false){
						_this.isSelected(!_this.isSelected());
					}
				}else{
					_this.publish({event:"click",value :_this});
				}
			};
		})(this,d));
		pimg = d.image;
		if(pimg){
			prot = pimg.substr(4,1);
			if(ishttps===true && prot === ":"){
				pimg = "https" + pimg.substr(4,pimg.length);
			}else if(prot==="https"){
				pimg = "http:" + pimg.substr(5,pimg.length);
			}
		}
		div = doc.createElement("div");
		$(div).addClass("item");
		img = $(doc.createElement("img")).
			attr("src",((pimg)?"people/getimage?req="+encodeURI(d.lastUpdated)+"&id="+d.id: appdb.config.images.person)).addClass("itemimage");
		span = $(doc.createElement("span")).append(fullname).addClass("itemname");
		if(isos.length>1){
			$(span).addClass("flagcount"+isos.length);
		}
		span1 = $("<span></span>").append(unescape(d.role.type)+"<br/>"+(d.institute.substring(0,80))+((d.institute.length>80)?'...':'')).addClass("itemsorttext");
		span2 = $("<span></span>").append(unescape(d.role.type)+"<br/>"+((d.institute)?d.institute+', ':'')+d.country.val()+"<br/>Registered since "+d.registeredOn).addClass("itemlongtext");
		$(a).append(img);
		$(a).append(flags);
		$(a).append(span);
		$(a).append(span1);
		$(a).append(span2);
		$(div).append($(a));
		$(this.dom).append(div);
		
		this.renderContactPoints();
		this.renderSelectable();
	};
	this.reset = function(){
		$(this.dom).find("div > a").each(function(index,elem){
			$(this).unbind("click");
		});
		$(this.dom).empty();
	};
});
appdb.views.RelatedContactList = appdb.ExtendClass(appdb.views.List,"appdb.views.RelatedContactList",function(o){
	this._permissions =null;
	this._application = null;
	this.canSetContactPoint = true;
	this.excludedDataItems = new appdb.utils.UniqueDataList();
	this.selectedDataItems = new appdb.utils.UniqueDataList();
	this.addNewContacts = function(cnts){
		cnts = cnts || [];
		cnts = $.isArray(cnts)?cnts:[cnts];
		var i, len = cnts.length;
		for(i=0; i<len; i+=1){
			cnts[i].isNew = true;
			this._listData[this._listData.length] = cnts[i];
		}
	};
	this.setupForm = function(frm){
		if(typeof frm === "undefined"){
			return;
		}
		var i , j, v = this.subviews, len = v.length, index = 0,inp;
		for(i=0; i<len; i+=1){
			if(v[i].isSelected()==false){
				inp = document.createElement("input");
				$(inp).attr("type","hidden").attr("name","scicon"+index).attr("value",v[i]._itemData.id);
				$(frm).append(inp);
				index+=1;
			}
		}
		index = 0;
		for(i=0; i<len; i+=1){
			if(v[i].isSelected()==false){
				var c = v[i]._itemData || {};
				var ca = c.contactItem || [];
				ca = ($.isArray(ca)==true)?ca:[ca];
				for(j=0; j<ca.length; j+=1){
					var ci = ca[j];
					if(typeof ci.toRemove !== "undefined"){
						if(ci.toRemove==true){
							continue;
						}
					}
					if(typeof ci.toRemoveImplicit != "undefined"){
						if(ci.toRemoveImplicit == true){
							continue;
						}
					}
					inp = document.createElement("input");
					if(ci.id.indexOf(":")>-1){
						ci.id = ci.id.split(":")[0];
					}
					var jsn = {researcherid : c.id , itemtype: ci.type.toLowerCase() , itemid : ((ci.type.toLowerCase()=='other')?'':ci.id), item : $("<span>"+ci.val()+"</span>").text()};
					$(inp).attr("type","hidden").attr("name","cntpnt"+index).attr("value",JSON.stringify(jsn));
					$(frm).append(inp);
					index+=1;
				}
			}
		}
		//$(frm).find(":input").each(function(index,elem){if($(elem).attr("name")=="documents" || $.trim($(elem).attr("name"))=='' ) return;console.log($(elem).attr("name") + " : " + $(elem).attr("value"));});
	};
	this._constructor = function(){
		if(o.data){
			if($.isArray(o.data)){
				this._listData  = o.data;
			}else if(o.data.contact){
					if($.isArray(o.data.contact) == false){
						this._listData = [o.data.contact];
					}else{
						this._listData = o.data.contact;
					}
					this._application = o.data;
			}
		}
		if(typeof o.canSetContactPoint !== "undefined"){
			this.canSetContactPoint = o.canSetContactPoint;
		}
		if($.isArray(o.excluded)){
			this.excludedDataItems = new appdb.utils.UniqueDataList({data : o.excluded});
		}
		if($.isFunction(o.onExclude)){
			this.onExclude = o.onExclude;
		}
		if(o.permissions && o.permissions.action){
			this._permissions = new appdb.utils.Privileges(o.permissions);
			if(this._permissions.canDisassociatePersonFromApplication()){
				this.onBeforeItemRender = function(li){
					if(o.useToggleButton){
						li.useToggleButton = o.useToggleButton;
					}
					li.isSelectable = true;
					li.canSetContactPoint = this.canSetContactPoint;
					return li;
				};
				this.onAfterItemRender = function(li){
					if(this.selectedDataItems.has(li._itemData)){
						li.isSelected(true);
					}
					if(this.excludedDataItems.has(li._itemData)){
						$(li.dom).addClass("excluded");
						if(this.onExclude){
							this.onExclude(li);
						}
					}
				}
			}
		}
		this.setListType(appdb.views.RelatedContactListItem);
		this.itemSubscriptions = [
			{event:"click",callback:function(elem){
				var data = elem._itemData;
				if(this.parent && this.parent.views.pager){
					this.publish({event:"itemclick",value : {list : this, item : elem}});
				}else{
					appdb.views.Main.showPerson({id:data.id},{mainTitle : data.firstname + " " + data.lastname,append:true});
				}
			},caller : this},
			{event : "selected", callback : function(elem){
					if(elem.isSelected()){
						this.selectedDataItems.add(elem._itemData);
					}else{
						this.selectedDataItems.remove(elem._itemData);
					}
					this.publish({event : "itemselected",value : {list:this,item:elem}});
			},caller : this}
		];
		$(this.dom).addClass("relatedcontacts");
		this.postRender = function(){
			setTimeout((function(_this){
				return function(){
					if(_this.EditMode()){
						_this.checkForChanges();
					}
				};
			})(this),10);
		};
	};
	this.checkForChanges = function(){
		var i, items = this.subviews || [], len = items.length;
		for(i=0; i<len; i+=1){
			if(items[i]._itemData){
				appdb.views.RelatedContactList.CheckForChanges.apply(this,[items[i]]);
			}
		}
	};
	this.hasChanges = function(){
	 var i, len = this.subviews.length;
	 for(i=0; i<len; i+=1){
	  if(this.subviews[i].hasChanges()){
	   return true;
	  }
	 }
	 return false;
	};
	this.EditMode = (function(_this){
		var inEdit = false;
		return function(isedit){
			if(typeof isedit !== "undefined"){
				if(isedit==true){
					inEdit = true;
					$(_this.dom).addClass("editmode");
				}else{
					inEdit = false;
					$(_this.dom).removeClass("editmode");
				}
			}
			return inEdit;
		};
	})(this);
	this._constructor();
},{
	ChangesDialog : null,
	CheckForChanges : function(item){
		var i, len, ischanged = {contactpoints : {value : false, reasons : []}, contact : {value:false, reasons:[]}}, changeset = [],data = item._itemData || item, d = data.contactItem || [];
		if((typeof data.isNew != "undefined" && data.isNew==true )){
			if(((typeof data.toRemove != "undefined" && data.toRemove==true) || (typeof data.toRemoveImplicit != "undefined"  && data.toRemoveImplicit == true))==false){
				ischanged.contact.value = true;
				ischanged.contact.reasons[ischanged.contact.reasons.length] = "Newly added contact.";
			}
		}else if((typeof data.toRemove != "undefined"  && data.toRemove == true) || (typeof data.toRemoveImplicit != "undefined"  && data.toRemoveImplicit == true)){
			if((typeof data.isNew != "undefined" && data.isNew==true)==false){
				ischanged.contact.value = true;
				ischanged.contact.reasons[ischanged.contact.reasons.length] = "Remove contact.";
			}
		}

		if($.isArray(d) ==  false){d = [d];}
		len = d.length;
		for(i=0; i<len; i+=1){
			if((typeof d[i].isNew != "undefined" && d[i].isNew==true )){
				if(((typeof d[i].toRemove != "undefined" && d[i].toRemove==true) || (typeof d[i].toRemoveImplicit != "undefined"  && d[i].toRemoveImplicit == true))==false){
					ischanged.contactpoints.value = true;
					break;
				}
			}else if((typeof d[i].toRemove != "undefined"  && d[i].toRemove == true) || (typeof d[i].toRemoveImplicit != "undefined"  && d[i].toRemoveImplicit == true)){
				if((typeof d[i].isNew != "undefined" && d[i].isNew==true)==false){
					ischanged.contactpoints.value = true;
					break;
				}
			}
		}
		if(ischanged.contactpoints.value==true){
			ischanged.contactpoints.reasons[ischanged.contactpoints.reasons.length] = "Changes in expertise";
		}

		changeset = ischanged.contact.reasons.concat(ischanged.contactpoints.reasons);
		if(changeset.length>0){
			if(ischanged.contactpoints.value == true){
				if($(".contactpointlistcontainer").find(".mustsave").length==0){
					$(".contactpointlistcontainer").append("<div class='mustsave' ><img src='images/diskette.gif' title='' alt=''/><span>The application needs to be saved first for the changes to take effect.</span></div>")
					$(".contactpointlistcontainer").find(".nodata").remove();
				}
			}
			if($(item.dom).find(".haschanges").length>0){
				$(item.dom).find(".haschanges").remove();
			}
			if($(item.dom).find(".haschanges").length==0){
				var span = document.createElement("span");
				$(span).addClass("haschanges").append("<img src='images/diskette.gif' />");
				$(item.dom).append(span);
				$(span).mouseover(function(){
					if(appdb.views.RelatedContactList.ChangesDialog!=null){
						dijit.popup.close(appdb.views.RelatedContactList.ChangesDialog);
						appdb.views.RelatedContactList.ChangesDialog.destroyRecursive(false)
						appdb.views.RelatedContactList.ChangesDialog = null;
					}
					var msg = "<div style='font-size:10px;width:200px;'>There are changes regarding this contact listed bellow.<ul style='padding-top:4px;padding-bottom:3px;padding-left:14px;'>";
					for(var i =0; i<changeset.length; i+=1){
						msg += "<li style='padding-left:2px;margin-left:0px;'>" + changeset[i] + "</li>";
					}
					msg += "</ul><div>changes will take effect after saving the application.</div></div>";
					appdb.views.RelatedContactList.ChangesDialog = new dijit.TooltipDialog({content : msg});
                    dijit.popup.open({
                        parent : span,
                        popup: appdb.views.RelatedContactList.ChangesDialog,
                        around : span,
                        orient: {'TL':'BL','TR':'BR'}
                    });
				}).mouseleave(function(){
					if(appdb.views.RelatedContactList.ChangesDialog!=null){
						dijit.popup.close(appdb.views.RelatedContactList.ChangesDialog);
						appdb.views.RelatedContactList.ChangesDialog.destroyRecursive(false)
						appdb.views.RelatedContactList.ChangesDialog = null;
					}
				});
			}
		}else{
			$(".contactpointlistcontainer").find(".mustsave").remove();
			if(len==0 && $(".contactpointlistcontainer").find("table tbody tr.nodata").length==0 && this._renderNoData){
				$(".contactpointlistcontainer").find("table tbody").append(this._renderNoData());
			}
			$(item.dom).find(".haschanges").remove();
		}
	}
});

appdb.views.ContactPointEditor = appdb.ExtendClass(appdb.View,"appdb.views.ContactPointEditor",function(o){
	this.listItem  = null;
	this._application = null;
	this._dialog  = null;
	this.vos = [];
	this.mws = [];
	this._getAvailableVOs = function(){
		var voids = [];
		var res = [];
		var vod =  eval("("+voData+")");
		$(":input[name^='vo']").each(function(){
			voids[voids.length] = $(this).val();
		});
		for(var j=0; j<voids.length; j+=1){
			var voindex = -1;
			for(var i=0; i<vod.ids.length; i+=1){
				if(voids[j]==vod.ids[i]){
					voindex = i;
					break;
				}
			}
			if(voindex>-1){
				res[res.length] = {id:vod.ids[voindex],name:vod.vals[voindex]};
				if(res.length==voids.length){
					break;
				}
				voindex = -1;
			}
		}
		return res;
	};
	this._getUnusedVos = function(vos){
		var u = {}, res = [], cp = ((this.listItem._itemData)?this.listItem._itemData.contactItem:[]) || [];
		if($.isArray(cp) == false){
			cp = [cp];
		}
		for(var i=0; i<vos.length; i+=1){
			var index = -1;
			for(var j=0; j<cp.length; j+=1){
				if(cp[j].type == "vo" && cp[j].id==vos[i].id){
					index = i;
					break;
				}
			}
			if(index===-1){
				u[vos[i].id] = vos[i];
			}
		}
		for(i in u){
			res[res.length] = u[i];
		}
		return res;
	};
	this._getAvailableMiddlewares = function(){
		var mwids = [];
		var res  =[];
		var mw = eval("("+mwData+")");
		$(":input[name^='mw']").each(function(){
			if($.trim($(this).val())!='' && $(this).val()!=appdb.config.defaults.api.middleware){
				mwids[mwids.length] = $(this).val();
			}
		});
		for(var j=0; j<mwids.length; j+=1){
			var mwindex = -1;
			for(var i=0; i<mw.ids.length; i+=1){
				if(mwids[j]==mw.vals[i] ){
					mwindex = i;
					break;
				}
			}
			if(mwindex>-1){
				res[res.length] = {id:mw.ids[mwindex],name:mw.vals[mwindex],comment:''};
			}else{
				res[res.length] = {id:5,name:"Other",comment:mwids[j]};
			}
			if(res.length==mwids.length){
				break;
			}
		}
		return res;
	};
	this._getUnusedMiddlewares = function(mws){
		var u = {}, res = [], cp = ((this.listItem._itemData)?this.listItem._itemData.contactItem:[]) || [];
		if($.isArray(cp) == false){
			cp = [cp];
		}
		for(var i=0; i<mws.length; i+=1){
			var index = -1;
			for(var j=0; j<cp.length; j+=1){
				if(cp[j].type.toLowerCase() == "middleware"){
					if(mws[i].id == 5 && cp[j].id.indexOf(":")>-1 && mws[i].comment && $.trim(mws[i].comment)!='' && cp[j].id==(mws[i].id + ":" + mws[i].comment)){
						index = i;
						break;
					}else if(cp[j].id+'' == mws[i].id+'' && $.trim(mws[i].comment)==""){
						index = i;
						break;
					}
				}
			}
			if(index===-1){
				if(mws[i].comment){
					u[mws[i].id+":"+$.trim(mws[i].comment)] = mws[i];
				}else{
					u[mws[i].id] = mws[i];
				}
			}
		}
		for(i in u){
			res[res.length] = u[i];
		}
		return res;
	};
	this._isImplicitRemove = function(d){
		var type = d.type.toLowerCase();
		if(type == "other"){
			return false;
		}
		var i, data = [], len = data.length, index = -1;
		if(type=="middleware"){
			data = this._getAvailableMiddlewares();
			len = data.length;
			for(i=0; i<len; i+=1){
				if(d.id == data[i].id){
					index = i;
					break;
				}else if(data[i].id==5){
					if(d.id == data[i].id+":"+data[i].comment){
						index = i;
						break;
					}
				}
			}
		}else{
			data = this._getAvailableVOs();
			len = data.length;
			for(i=0; i<len; i+=1){
				if(d.id == data[i].id){
					index = i;
					break;
				}
			}
		}
		if(index >-1){
			return false;
		}
		return true;
	};
	this._animateTableRow = function(v){
		var td = null;
		$(".contactpointlistcontainer table tr td.celltype").each(function(){
			if($(this).next("td.cellvalue").text().toLowerCase()==v.toLowerCase()){
				td = this;
			}
		});
		if(td != null) {
			var tr =  $(td).parent();
			var prevColor = $(td).css("background-color") || "";

			$(tr).animate({"opacity":"0.5","background-color":"red"},300,function(){setTimeout(function(){$(tr).animate({"opacity":"1","background-color":prevColor},400);},10);});
		}
	};
	this._canAddOtherText = function(v){
		if($.trim(v)==''){
			return false;
		}
		var i, len, data = this.listItem._itemData.contactItem || [];
		if($.isArray(data)==false){
			data = [data];
		}
		len = data.length;
		for(i=0; i<len; i+=1){
			var vv = data[i].val();
			if($.trim(vv).toLowerCase()==$.trim(v).toLowerCase()){
				this._animateTableRow(v);
				return false;
			}
		}
		return true;
	};
	this._renderDataEntry = function(item,container){
		var dbn = dijit.byId("contactpointlistbutton"), cnt = document.createElement("span"), renderdata = [];
		if(dbn) {
			dbn.destroyRecursive(false);
		}
		$(container).empty();
		$(cnt).addClass(".contactpointdata");
		$(container).append(cnt);

		if(item.type=='list'){
			var list = item.data;
			for(var i=0; i<list.length; i+=1){
				var d = list[i];
				if(item.name=='Middleware' && d.id==5 && $.trim(d.comment)!=''){
					renderdata[renderdata.length] = {label:d.comment,value:d.id+":"+d.comment};
				}else{
					renderdata[renderdata.length] = {label:d.name,value:d.id};
				}
			}
			new dijit.form.Select({
				name : "contactpointlistbutton",
				style : "width:130px;",
				options : renderdata,
				id: "contactpointlistbutton",
				onChange : function(v){
					jQuery.data($(".contactpointcommand.add:last")[0],"data",{type:item.name,value:v,display:this.getOptions(v).label});
					$(".contactpointcommand.add").css({"display":"inline-block"});
				}
			},cnt);
		}else{
			new dijit.form.TextBox({
				value : '',
				style : "height:17px;width:140px;vertical-align:middle;",
				placeHolder : "Provide a value...",
				onKeyUp: (function(_this){
					return function(){
						if(_this._canAddOtherText(this.getDisplayedValue())){
							jQuery.data($(".contactpointcommand.add:last")[0],"data",{type:item.name,value:this.getDisplayedValue()});
							$(".contactpointcommand.add").css({"display":"inline-block"});
						}else{
							jQuery.data($(".contactpointcommand.add:last")[0],"data",null);
							$(".contactpointcommand.add").hide();
						}
				};})(this),
				onChange : (function(_this){
					return function(v){
						if(_this._canAddOtherText(v)){
							jQuery.data($(".contactpointcommand.add:last")[0],"data",{type:item.name,value:v,display:v});
							$(".contactpointcommand.add").css({"display":"inline-block"});
						}else{
							jQuery.data($(".contactpointcommand.add:last")[0],"data",null);
							$(".contactpointcommand.add").hide();
						}
				};})(this)},cnt);
			$(".contactpointcommand.add").hide();
		}
		
		if(item.type=='list'){
			jQuery.data($(".contactpointcommand.add:last")[0],"data",{type:item.name,value:renderdata[0].value,display:renderdata[0].label});
		}else{
			jQuery.data($(".contactpointcommand.add:last")[0],"data",'');
		}
		if(item.data){
			$(".contactpointcommand.add").css({"display":"inline-block"});
		}
	};
	this._renderAdder = function(data){
		var typebutton, div = document.createElement("div"), types = document.createElement("span"), 
			lists = document.createElement("span"), add = document.createElement("span"), button = document.createElement("span");
		this.dom = div;
		$(div).addClass("contactpointadder");
		$(types).addClass("contactpointtypemenu");
		$(lists).addClass("contactpointdata");
		$(add).addClass("contactpointcommand").addClass("add").attr("title","Add item").css({"display":"inline-block"}).append(button).hide();
		$(div).append(types);
		$(div).append(lists);
		$(div).append(add);

		var typemenu = new dijit.Menu({
            style: "display: none;"
        });
		for(var i in data){
			if(data[i].type == "list" && data[i].data.length>0){
				typemenu.addChild(new dijit.MenuItem({
					label: data[i].name,
					onClick: (function(_this,item){
						return function() {
							typebutton.attr("label",item.name);
							_this._renderDataEntry(item,lists);
						};
					})(this,data[i])
				}));
			}
		}
		typemenu.addChild(new dijit.MenuItem({
			label: "Custom",
			onClick: (function(_this,item){
				return function() {
					typebutton.attr("label","Custom");
					_this._renderDataEntry(item,lists);
				};
			})(this,data[i])
		}));
		typebutton = new dijit.form.DropDownButton({
            label: "Select a subject",
			"class": "WhiteDojoButton",
            name: "contactpointtypebutton",
            dropDown: typemenu
        },$(types)[0]);

		new dijit.form.Button({
			label : "add",
			onClick : (function(_this){
				return function(){
					var d = jQuery.data($(".contactpointcommand.add:last")[0],"data");
					var res = null;
					if(d.type=='Virtual Organization'){
						d.type = "vo";
					}
					if(d){
						res = {type : d.type , id: d.value, val: (function(val){return function(){return val;};})(d.display)};
					}
					_this._addNewContactPoint(res);
				};
			})(this,data)
		},button);
		return div;
	};
	this._addNewContactPoint = function(data){
		if(typeof this.listItem._itemData.contactItem === "undefined"){
			this.listItem._itemData.contactItem = [];
		}
		if($.isArray(this.listItem._itemData.contactItem)==false){
			this.listItem._itemData.contactItem = [this.listItem._itemData.contactItem];
		}
		data.isNew = true;
		if(data.type.toLowerCase()=="other"){
			data.val = (function(_data){return function(){return _data;};})(data.id);
			data.id = "0";
		}
		this.listItem._itemData.contactItem[this.listItem._itemData.contactItem.length] = data;

		var pa = $(".contactpointeditor .contactpointadder");
		$(pa).after(this._renderAdder({
				"vo" : {name : "Virtual Organization", type : "list", data : this._getUnusedVos(this._getAvailableVOs()), "default" : "Select a value..."},
				"mw" : {name : "Middleware", type : "list", data : this._getUnusedMiddlewares(this._getAvailableMiddlewares()), "default" : "Select a value..."},
				"other" : {name : "Other", type : "text", "default" : "Select a value..."}
		}));
		$(pa).remove();

		var tbl = $(".contactpointlistcontainer table tbody");
		var tr = this._renderContactPointRow(data);
		$(tbl).append(tr);
	};
	this._removeContactPoint = function(data){
		var l = this.listItem._itemData.contactItem, len = l.length, i, index=-1;
		for(i=0; i<len; i+=1){
			if(l[i].isNew && l[i].isNew==true && l[i].id == data.id){
				index = i;
				break;
			}
		}
		if(index>-1){
			this.listItem._itemData.contactItem.splice(index,1);
		}
		var pa = $(".contactpointeditor .contactpointadder");
		$(pa).after(this._renderAdder({
				"vo" : {name : "Virtual Organization", type : "list", data : this._getUnusedVos(this._getAvailableVOs()), "default" : "Select a value..."},
				"mw" : {name : "Middleware", type : "list", data : this._getUnusedMiddlewares(this._getAvailableMiddlewares()), "default" : "Select a value..."},
				"other" : {name : "Other", type : "text", "default" : "Select a value..."}
		}));
		$(pa).remove();

	};
	this._renderContactPointRow = function(data){
		var tr = document.createElement("tr"), tdflag=document.createElement("td"), tdtype = document.createElement("td"), tdvalue = document.createElement("td"),
			tdremove = document.createElement("td"), button = document.createElement("span"), dojobutton ;
		var type = "Virtual Organization";
		if(data.type.toLowerCase()=="middleware"){
			type = "Middleware";
		}else if (data.type.toLowerCase()=="other"){
			type = "Other";
		}
		var isremoveimplicit = this._isImplicitRemove(data);
		if(data.toRemoveImplicit && isremoveimplicit==false){
			delete data.toRemoveImplicit;
		}else if(isremoveimplicit==true){
			data.toRemoveImplicit = true;
		}
		$(tdflag).addClass("cellflag").append("<img class='toadd' src='images/"+((data.isNew)?"close":"close2")+".png' title='This item will be "+ ((data.isNew)?"added":"removed") +" after saving the application.' />");
		$(tdtype).addClass("celltype").append("<div>" + type + "</div>");
		$(tdvalue).addClass("cellvalue").append("<div>" + ((data.val)?data.val():'') + "</div>");
		$(tdremove).addClass("cellcommand");
		$(tr).append(tdflag).append(tdtype).append(tdvalue).append(tdremove);
		$(tdremove).append(button);
		if(data.isNew){
		   dojobutton = new dijit.form.Button({
			   label : "remove",
			   iconClass :"dijitIconDelete",
			   onClick : (function(_this,d){
				   return function(){
						_this._removeContactPoint(d);
						$(tr).remove();
						if(_this.listItem._itemData.contactItem.length==0){
							$(".contactpointlistcontainer table thead").hide();
						}
						_this._checkForChanges();
				   };
			   })(this,data)
		   },button);
			if(data.toRemoveImplicit){
				var msg = "<div class='removeimplicitmessage' >The " + type.toLowerCase() + " '<i><b>" + ((data.val)?data.val():'') + "</b></i>' will be removed from this application. All contact expertise of the same type will be removed as well after saving the application. To prevent this go to the application's " + type.toLowerCase() + " list and add '<i>" + data.val() + "</i>' again.<div>";
				var pu =  new dijit.TooltipDialog({content : msg});
				dojo.connect(dojobutton, "onMouseEnter",this,function(){
						setTimeout((function(_this){
							pu =  new dijit.TooltipDialog({content : msg});
							return function(){
								dijit.popup.open({
									parent : dojobutton.domNode,
									popup: pu,
									around : dojobutton.domNode,
									orient: {'BL':'TL','BR':'TR'}
								});
						};})(this),1);
				});
				dojo.connect(dojobutton,"onMouseLeave",this,function(){
						if(pu){
							dijit.popup.close(pu);
							pu.destroyRecursive(false);
						}
				});
				$(tdremove).mouseleave(function(){
					if(pu){
						dijit.popup.close(pu);
						pu.destroyRecursive(false);
					}
					
				});
				$(tr).addClass("toremove");
			}//end of explicitremove
		} else {
			dojobutton = new dijit.form.ToggleButton({
				showLabel : true,
				label : "remove",
				iconClass :"dijitCheckBox",
				title : (data.toRemove)?"This entry is marked to be removed after saving the  application.":"Mark this entry to be removed",
				disabled : (data.toRemoveImplicit)?true:false,
				checked : (data.toRemoveImplicit || data.toRemove)?true:false,
				onMouseUp : function(){
					if(data.toRemoveImplicit){
						var msg = "<div class='removeimplicitmessage' >The " + type.toLowerCase() + " '<i><b>" + ((data.val)?data.val():'') + "</b></i>' will be removed from this application. All contact expertise of the same type will be removed as well after saving the application. To prevent this go to the application's " + type.toLowerCase() + " list and add '<i>" + data.val() + "</i>' again.<div>";
						var pu =  new dijit.TooltipDialog({content : msg});
						setTimeout((function(_this){
							return function(){
								dijit.popup.open({
									parent : _this.domNode,
									popup: pu,
									around : _this.domNode,
									orient: {'BL':'TL','BR':'TR'}
								});
						};})(this),1);
					}
				},
				onChange : (function(_this) {
					return function(v){
						if(data.toRemoveImplicit){
							this.attr("title","")
							$(this.domNode).find(".dijitCheckBox:first").addClass("dijitCheckBoxChecked").addClass("dijitChecked");
							return false;
						}
						if(v==true){
							data.toRemove = v;
							this.attr("title","This entry is marked to be removed after saving the  application.");
							$(this.domNode).find(".dijitCheckBox:first").addClass("dijitCheckBoxChecked").addClass("dijitChecked");
							$(tr).addClass("toremove");
						}else{
							delete data.toRemove;
							this.attr("title","Mark this entry to be removed");
							$(tr).removeClass("toremove");
							$(this.domNode).find(".dijitCheckBox:first").removeClass("dijitCheckBoxChecked").removeClass("dijitChecked");
						}
						_this._checkForChanges();
					};
				})(this)
			},button);
			if(dojobutton.attr("checked")){
					$(dojobutton.domNode).find(".dijitCheckBox:first").addClass("dijitCheckBoxChecked").addClass("dijitChecked");
					if(data.toRemoveImplicit){
						dojobutton.attr("title","");
					}
			}
			if(data.toRemove==true || data.toRemoveImplicit==true){
				$(tr).addClass("toremove")
			}else{
				$(tr).removeClass("toremove");
			}
		}
		if(data.isNew==true){
			$(tr).addClass("toadd");
		}
		this._checkForChanges();
		 $(".contactpointlistcontainer table thead").show();
		return tr;
	};
	this._renderNoData = function(){
		var tr = document.createElement("tr"), td = document.createElement("td"),data  = this.listItem._itemData;
		$(tr).addClass("nodata");
		$(td).attr("colspan","4");
		$(td).text("No expertise has been set yet");//data.firstname + " " + data.lastname + " is not registered as a contact point for this application.");
		$(tr).append(td);
		return tr;
	};
	this._renderContactPoints = function(data){
		var list = data.contactItem || [];
		if($.isArray(list)==false){list = [list];}
		var div = document.createElement("div"), table = document.createElement("table"), tbody = document.createElement("tbody"),thead = document.createElement("thead");
		$(div).addClass("contactpointlistcontainer");
		$(table).attr("cellpadding","0").attr("cellspacing","0");
		$(table).append(tbody);
		$(div).append(table);
		$(thead).append("<tr><th align='left' colspan='2'>Type</th><th align='left' colspan='2'>Value</th></tr>");
		$(table).append(thead);
		if(list.length>0){
			for(var i =0; i<list.length; i+=1){
				$(tbody).append(this._renderContactPointRow(list[i]));
			}
		}else{
			$(thead).hide();
			$(tbody).append(this._renderNoData());
		}
		return div;
	};
	this._checkForChanges = (function(_this){
		return function(){appdb.views.RelatedContactList.CheckForChanges.apply(_this,[_this.listItem]);};
	})(this);
	this.render = function(){
		var d = this.listItem._itemData;
		var div = document.createElement("div"), title = document.createElement("div"), commands = document.createElement("div");
		if(appdb.views.ContactPointEditor.Dialog!=null){
			appdb.views.ContactPointEditor.Dialog.hide();
			appdb.views.ContactPointEditor.Dialog.destroyRecursive(false);
		}
		
		$(div).addClass("contactpointeditor");
		$(title).addClass("title");
		$(commands).addClass("contactpointactions");
		$(title).text("" +  d.firstname + " " + d.lastname + " will be displayed as an expert regarding this application on the subjects listed bellow:");
		$(div).append(title);

		$(div).append(this._renderAdder({
				"vo" : {name : "Virtual Organization", type : "list", data : this._getUnusedVos(this._getAvailableVOs()), "default" : "Select a value..."},
				"mw" : {name : "Middleware", type : "list", data : this._getUnusedMiddlewares(this._getAvailableMiddlewares()), "default" : "Select a value..."},
				"other" : {name : "Other", type : "text", "default" : "Select a value..."}
		}));

		$(div).append(this._renderContactPoints(d));
		$(div).append(commands);
		
		new dijit.form.Button({
            label: "Close",
			style: "float:right;padding:5px;",
            onClick: function() {
                appdb.views.ContactPointEditor.Dialog.hide();
            }
        },$(commands)[0]);
		this._checkForChanges();
		appdb.views.ContactPointEditor.Dialog = new dijit.Dialog({
			title: "Edit expertise",
			style : "width:470px",
			content: $(div)[0]
		});
		appdb.views.ContactPointEditor.Dialog.show();
		setTimeout((function(_this){return function(){_this._checkForChanges();};})(this),1);
	};
	this._constructor = function(){
		this.listItem = o.listitem;
		this.vos = this._getUnusedVos(this._getAvailableVOs());
		this.mws = this._getUnusedMiddlewares(this._getAvailableMiddlewares());
	};
	this._constructor();
},{
	Dialog : null,
	WarningDialog: null
});

appdb.views.AppsList = appdb.ExtendClass(appdb.View, "appdb.views.AppsList", function(o){
	this._addItem = function(d,index){
		var doc = document, a, img, span, span1, span2, more, div, div1, i, u = [], res = $(doc.createElement("li")), logo, ishttps =  Boolean(appdb.config.https) && true, prot, moderated = false, deleted = false, title = '';
		title = d.name;
		if(d.moderated){
			if (Boolean(d.moderated) == true) {
				moderated = true;
				$(res).addClass("moderated");
				title = "This application has been moderated.";
				$(res).attr("title",title);
			}
		}
		if(d.deleted){
			if (Boolean(d.deleted) == true) {
				deleted = true;
				$(res).addClass("deleted");
				title = "This application has been deleted.";
				$(res).attr("title",title);
			}
		}
		$(res).addClass("itemcontainer");
		div = doc.createElement("div");
		$(div).addClass("item");

		a = $(doc.createElement("a")).attr("title",title);
		$(a).addClass("itemlink");
		$(a)[0].onclick = (function(_this,data){
			return function(){
				 if(_this.parent && _this.parent.views.pager){
					_this.publish({event:"itemclick",value : data});
				 }else{
					appdb.views.Main.showApplication(data);
				 }
			};
		})(this,d);
		logo =  d.logo;
		if(logo){
			prot = logo.substr(4,5);
			if(ishttps===true && prot === ":"){
				logo = "https" + logo.substr(4,logo.length);
			}else if(prot==="https"){
				logo = "http:" + logo.substr(5,logo.length);
			}
		}
		img = $(doc.createElement("img")).
			attr("src",((logo)?"apps/getlogo?req="+encodeURI(d.lastUpdated)+"&id="+d.id: ((d.tool==="true")?appdb.config.images.tool:appdb.config.images.application))).
			addClass("itemimage");
		$(a).append(img);
		span = $(doc.createElement("span")).append(d.name.substring(0,45)+(d.name.length>45?'...':'')).addClass("itemname");
		span1 = $(doc.createElement("span")).append(unescape(d.description.substring(0,80))+((d.description.length>80)?'...':'')).addClass("itemsorttext");
		span2 = $(doc.createElement("span")).append(unescape(d.description)).append(doc.createElement("p")).append(d["abstract"]).addClass("itemlongtext");
		more = $(doc.createElement("span")).addClass("itemmore").append("click for details");
		$(a).append(span).
			append(span1).
			append(span2).
			append(more);
		$(div).append($(a));
		if(d.url){
			u = ($.isArray(d.url))?d.url:[d.url];
		}
		$(div).append($(a));
		div1 = $(doc.createElement("div")).addClass("itemurlcontainer");
		if(u.length>0){
			/*for(i=0; i<u.length; i+=1){
				if ( u[i].val ) {
					$(div1).append($("<a href='"+u[i].val()+"' target='_blank' style='padding-right:5px;' >"+u[i].type+"</a>").addClass("itemurl"));
				}
			}*/
			var au = new appdb.views.ApplicationUrls({container : div1});
			this.subviews[this.subviews.length] = au;
			au.render(u);
		}else{
			$(div1).removeClass("itemurlcontainer").addClass("itemurlcontainer-empty");
		}
		$(div).append($(div1));
		$(res).append($(div));
		return res;
	};
	this.render = function(d){
		this.reset();
		var i, len = (d)?((typeof d.length !== "undefined")?d.length:len):0,  f = $(this.dom).context;
		$(this.dom).empty();
		if(typeof len === "undefined"){
			f.appendChild(this._addItem(d)[0]);
		} else if(len===0){
			f.appendChild($(document.createElement("span")).text("Nothing to display")[0]);
		}else{
			for(i=0; i<len; i+=1){
				f.appendChild(this._addItem(d[i],i)[0]);
			}
		}
	};
	this.destroy = function(){
		this.reset();
		$(this.dom).find("a").each(function(){
			$(this)[0].onclick = null;
		});
		$(this.dom).empty();
	};
    });
appdb.views.VOsList = appdb.ExtendClass(appdb.View,"appdb.views.VOslist",function(o){
        this._constructor = function(){
            if(typeof o.container === "string"){
                this.id = o.container;
                 if($(this.id).length>0){
                    this.dom = $($(this.id)[0]);
                }
            }else{
                this.id = $(o.container).attr("id");
                this.dom = $(o.container);
            }
        };
        this._addItem = function(d){
            var doc = document, a, img,span, span1, span2, div, div1, i, u = [], res = $(doc.createElement("li")),logo,domain='',desc_s,desc;
            if(d.discipline){
                domain = d.discipline;
                logo = d.discipline;
                while(logo.indexOf(" ")!==-1){
                    logo = logo.replace(" ","+");
                }
                logo = "vo/getlogo?id=" + logo;
            }else{
                logo = "";
            }
            if(d.val){
                desc = d.val();
            }
            if(desc){
                desc_s = unescape(desc.substring(0,80))+((desc.length>80)?'...':'');
                desc =  unescape(desc)
            }
            $(res).addClass("itemcontainer");
            div = $(doc.createElement("div")).addClass("item");
            a = $(doc.createElement("a")).attr("title",d.name).addClass("itemlink");
            $(a)[0].onclick = (function(_this,data){
                return function(){
                     if(_this.parent && _this.parent.views.pager){
                        _this.publish({event:"itemclick",value : data});
                     }else{
                        appdb.views.Main.showVO(data.name);
                     }
                };
            })(this,d);
            img = $(doc.createElement("img")).attr("src",logo).addClass("itemimage");
            span = $(doc.createElement("span")).append(d.name.substring(0,45)+(d.name.length>45?'...':'')).addClass("itemname");
            span1 = $(doc.createElement("span")).append(desc_s).addClass("itemsorttext");
            span2 = $(doc.createElement("span")).append(domain).append("<p></p>").append(desc).addClass("itemlongtext");

            $(a).append(img).
                append(span).
                append(span1).
                append(span2);
            $(div).append($(a));
            if(d.url){
                u = ($.isArray(d.url))?d.url:[d.url];
            }
            if(u.length>0){
                $(div).append($(a));
                div1 = $(doc.createElement("div")).addClass("itemurlcontainer");
                for(i=0; i<u.length; i+=1){
                    if ( u[i].val ) {
                        $(div1).append($("<a href='"+u[i].val()+"' target='_blank' style='padding-right:5px;'>"+u[i].type+"</a>")).addClass("itemurl");
                    }
                }
                $(div).append($(div1));
            }
            $(res).append($(div));
            return res;
        };
        this.render = function(d){
            var i, len = (d)?((typeof d.length !== "undefined")?d.length:len):0, f = $(this.dom).context;
            $(this.dom).empty();
            if(typeof len === "undefined"){
                f.appendChild(this._addItem(d)[0]);
            } else if(len===0){
                f.appendChild($(document.createElement("span")).text("Nothing to display")[0]);
            }else{
                for(i=0; i<len; i+=1){
                    f.appendChild(this._addItem(d[i])[0]);
                }
            }
            appdb.utils.animateList();
        };
        this.destroy = function(){
            $(this.dom).find("a").each(function(){
                $(this)[0].onclick = null;
            });
            $(this.dom).empty();
        };
        this._constructor();
    });

appdb.views.Publications = function(o){
    $.extend(this,new appdb.View(this));
    var _docgrid,_model;
    this.reset = function(){
        
    };
    this.getGridData = function(d){
        var j,i,data=[],title,pageStart,pageEnd;
        if(!d){
            return data;
        }
        if ($.isArray(d)==false) {d = [d]}
        for (i=0; i<d.length; i++) {
                var doc = d[i];
                if (doc.startPage == "") {
                        pageStart = doc.endPage;
                        pageEnd = "";
                } else {
                        pageStart = doc.startPage;
                        pageEnd = doc.endPage;
                }
                if (pageStart == "0") pageStart = "";
                if (pageEnd == "0") pageEnd = "";
                if (pageStart == pageEnd) pageEnd = "";
                var pages = ""+pageStart;
                if ( pageEnd != "" ) pages+=" - "+pageEnd;
                if (doc.url != "") {
                        title = "<a href=\""+doc.url+"\" target=\"_blank\">"+doc.title.replace(/'/g,"\\'")+"</a>";
                } else {
                        title = doc.title;
                }
                var authors = [];
                for (j=0; j<doc.author.length; j++) {
                        var author = doc.author[j];
                        var authorstr;
                        if (author.main) authorstr = "<b>";
                        if (author.type == "external") {
                                if(author.extauthor) {
								 authorstr += " "+author.extauthor.replace(/'/g,"\\'");
								}
                        } else {
                                //authorstr += " <a href=\"#\" onclick=\"showPplDetails(\'people/details?id="+author.person.id+"\')\">"+author.person.firstname.replace(/'/g,"\\'")+' '+author.person.lastname.replace(/'/g,"\\'")+"</a>";
                                authorstr += " <a href=\"#\" onclick=\"appdb.views.Main.showPerson({id:'"+author.person.id+"'},{mainTitle:'"+author.person.firstname+" "+author.person.lastname+"'})\">"+author.person.firstname.replace(/'/g,"\\'")+' '+author.person.lastname.replace(/'/g,"\\'")+"</a>";
                        }
                        if (author.main) authorstr += "</b>";
                        authors.push(authorstr);
                }
                data.push([/*doc.id,*/ [title], doc.type.val(), /*doc.type.id,*/ doc.conference, doc.volume, pages, doc.year, doc.publisher, doc.isbn, doc.proceedings, doc.journal, authors]);
        }
        return data;
    };
    this.render = function(d){
        this.reset();
        
        if(!d || d.length===0){
            if($("#ppl_details_no_pubs").length>0){
                $("#"+this.id).empty().append($("#ppl_details_no_pubs").html());
            }
            return;
        }
        var data = this.getGridData(d);
        var p = dijit.byId("personPublications");
        if(p){
            _docgrid = p;
        }else{
            this._init();
            _docgrid = new dojox.grid.Grid({id:"personPublications",style:'overflow:hidden'},this.id);
        }
        _model = new dojox.grid.data.Table(null, data);
        var view = {
        cells: [[
                //{name: 'ID', rowSpan: 2, width:'0%',hidden:true},
                {name: 'Title', rowSpan: 2, width:'20%'},
                {name: 'Type', rowSpan: 2, width:'5%'},
                //{name: 'TypeID', rowSpan: 2, width:'0%',hidden:true},
                {name: 'Conference', width:'20%'},
                {name: 'Volume', width:'5%'},
                {name: 'Pages', width:'5%'},
                {name: 'Year', width:'3%'},
                {name: 'Publisher', width:'10%'},
                {name: 'ISBN', width:'10%'}
            ],[
                {name: 'Proceedings'},
                {name: 'Journal', colSpan:3},
                {name: 'Authors', colSpan:2}
            ]]
        };
        _docgrid.setModel(_model);
        _docgrid.setStructure([view]);
        _docgrid.startup();
    };
    this.destroy = function(){
        this.clearObserver();
        if(_docgrid){
            if(_docgrid.destroy){
                _docgrid.destroyRecursive(false);
            }
            if(_model.destroy){
              _model.destroyRecursive(true);
            }
            _docgrid = null;
            _model = null;
        }
    };
    this._init = function(){
        var i = document.createElement("div");
        $(i).attr("id","personPublicationContainer")
        $("#"+o.container).append($(i));
        this.id = "personPublicationContainer";
        this.container = o.container;
    };
    this._init();
};
appdb.views.PersonImage = function(o){
    $.extend(this,new appdb.Template(o));
    var _default = "images/person.png";
    this.doRender = function(d){
        var _img = _default;
        if(d.image){
            _img = d.image;
        }
        $(this.viewDom).append("<span><img src='"+_img+"' alt=''width='110' height='110'></img></span>");
    };
    this.destroy = function(){
        $(o.dom).empty();
        o.dom = null;
    };
};

appdb.views.RoleValidation = appdb.ExtendClass(appdb.View,"appdb.views.RoleValidation",function(o){
    var _imgValid = "close.png",_imgInvalid = "close2.png";
	this._constructor = function(){
		if(typeof o.container === "string"){
			this.id = o.container;
			 if($(this.id).length>0){
				this.dom = $($(this.id)[0]);
			}
		}else{
			this.id = $(o.container).attr("id");
			this.dom = $(o.container);
		}
	};
    this.render = function(d){
        var v = d, _img = (v==='true'?_imgValid:_imgInvalid),_title = (v==='true'?"Role verified":"Pending role verification")
        $(this.dom).append("<img src='images/"+_img+"' alt='' title='"+_title+"' border='0'></img>");
    };
	this.destroy = function(){
		$(this.dom).empty();
	};
	this._constructor();
});
appdb.views.Flag = function(o){
  $.extend(this,new appdb.Template(o));
  this.doRender = function(d){
    var i,v = this.getDataItem(d).split("/"),_img;
    for(i=0; i<v.length; i+=1){
        _img = $("<img src='images/flags/"+v[i].toLowerCase()+".png' alt='' border='0'></img>");
        if(o.attr && o.attr.style){
            _img.attr("style",o.attr.style);
            $(this.dom).removeAttr("style");
        }
        $(this.viewDom).append(_img);
    }
  };
};

appdb.views.Export = appdb.ExtendClass(appdb.View, "appdb.views.Export", function(o){
      this.target = "";
      this.exportType = null;
      this.querydata = {};
      this.tooltip = null;
      this.form = null;
      this.exportCvs = null;
      this.exportXml = null;
      this.link = null;
      this.imgExport = null;
      this.isExporting = false;
      this.iframe = null;
      this.InProgressTooltip = null;
      this.query = "";
      this._constructor = function(){
          this.target = o.target;
      };
      this.reset = function(){
          if(this.tooltip){
            this.tooltip.destroy(false);
            this.InProgressTooltip.destroy(false);
            $(this.exportType).remove();
            $(this.exportXml).remove();
            $(this.exportCsv).remove();
            $(this.link).remove();
            $(this.iframe).remove();
            $(this.form).remove();
          }
          $(this.dom).empty();
      };
      this.submit = function(exType){
          var ifsrc = $(this.form).attr("action") + "?type="+exType + this.query;
          if(this.isExporting===true){
              return;
          }
          this.requestSendMessage();
          $(this.link).remove("iframe");
          this.iframe = null;
          this.iframe = $("<iframe src='"+ifsrc+"'></iframe>");
          $(this.iframe).hide();
          $(this.link).append(this.iframe);
      };
      this.requestSendMessage = function(){
          var _this = this;
          setTimeout(function(){
              dijit.popup.open({
                parent: $(_this.link)[0],
                popup: _this.InProgressTooltip,
                around: $(_this.link)[0],
                orient: {BR:'TR'}
            });
            dijit.popup.close(_this.tooltip);
            setTimeout(function(){
                dijit.popup.close(_this.InProgressTooltip);
            },10000);
          },30);
      };
      this.normalizeQuery = function(q){
        if(typeof q === "undefined"){
            return "";
        }
        if(typeof q === "object"){
            var res = "&";
            for(var i in q){
                res += i+"="+q[i];
            }
            q = res;
        }
        if(typeof q === "string"){
            if(q===""){
                q = '&flt=';
            }else{
                q="&flt="+encodeURIComponent(q);
            }
        }
        return q;
      };
      this.setValue = function(q){
          this.query = this.normalizeQuery(q);
      };
      this.render = function(){
        this.reset();
        var _this = this;
        this.link = $('<a title="Export results" href="#" ></a>');
        this.imgExport = $('<img border="0" height="29px" src="images/export.png" alt="export"/></a>');
        this.form = $('<form id="exportapps" name="exportapps" method="GET" action="'+appdb.config.endpoint.base+this.target+'/export"></form>');
        this.exportXml = $('<span style="white-space: nowrap;display:block;"><a title="Machine oriented, full data export" href="#">Export to XML</a> <a style="font-size:80%" target="_blank" href="files/app_xml_export.xsd">[XSD]</a></span>').click(function(){
            _this.submit('xml');
        });
        this.exportCsv = $('<span style="white-space: nowrap"><a title="Human oriented, concise data export" href="#">Export to CSV</a></span>').click(function(){
            _this.submit('csv');
        });
        $(this.form).append(this.exportXml);
        $(this.form).append(this.exportCsv);
        $(this.link).append(this.imgExport);
        $(this.link).append(this.form);
        //$(this.link).append(this.iframe);
        $(this.link).click(function(){
            dijit.popup.open({
                parent: $(_this.link)[0],
                popup: _this.tooltip,
                around: $(_this.link)[0],
                orient: {BR:'TR'}
            });
            return false;
        });
        this.tooltip =  new dijit.TooltipDialog({
                title: 'Filter',
                content:$(this.form)[0]
        });
         this.InProgressTooltip = new dijit.TooltipDialog({
                title: 'Filter',
                content:"<div style='width:280px'>The export request has been sent.You will be prompted for the generated data file in a while.</div>"
        });
        $(this.dom).append(this.link);
      };
      this._constructor();
  });
appdb.views.RatingAverage = appdb.ExtendClass(appdb.View,"appdb.views.RatingAverage",function(o){
	this.starBox = null;
	this._constructor = function(){
		if(typeof o.container === "string"){
            this.id = o.container;
             if($(this.id).length>0){
                this.dom = $($(this.id)[0]);
            }
        }else{
            this.id = $(o.container).attr("id");
            this.dom = $(o.container);
        }
		this.starBox = new appdb.views.StarBox({container : $("<span></span>"),isInteractive:false});
	};
	this.reset = function(){
		$(this.dom).empty();
	};
	this.render = function(d){
		this.reset();
		var s, as = 0, doc = document, title = $(doc.createElement("div")), average = $(doc.createElement("div")), descr = $(doc.createElement("div")), votecount = $(doc.createElement("div")), stars = $(doc.createElement("div"));
		$(this.dom).addClass("ratingaverage");
		//Render Title
		$(title).addClass("ratingaverage-title").text("Average value");
		$(this.dom).append($(title));

		//Render average number
		$(average).addClass("ratingaverage-value").text(d.average || "0");
		$(this.dom).append($(average));

		//Render textual representation of rating
		s = d.average;
		as = ratingToString(s); //this function exists in appdbgui.js file
		$(descr).addClass("ratingaverage-description").text(as || "unrated");
		$(this.dom).append($(descr));

		//Render stars
		$(this.dom).append($(stars));
		this.starBox.setContainer(stars).render(s);

		//Render total votes for specified type of voting
		$(votecount).html("<span class='ratingaverage-votecount'>votes:</span><span>"+d.total+"</span>");
		$(this.dom).append($(votecount));
	};
	this.destroy = function(){
		this.reset();
	};
	this._constructor();
});
appdb.views.StarBox = appdb.ExtendClass(appdb.View,"appdb.views.StarBox",function(o){
	this.starCount = 5;
	this.isInteractive = false;
	this.images = $.extend({},appdb.views.StarBox.images);
	this.classname = $.extend({},appdb.views.StarBox.classname);
	this.style = '';
	this._constructor = function(){
		if(o.images){
			this.images = $.extend(this.images,o.images);
		}
		if(typeof o.classname === "string" && $.trim(o.classname)!==""){
			for(var i in this.classname){
				this.classname[i] = o.classname;
			}
		}else if(typeof o.classname === "object"){
			this.classname = $.extend(this.classname,o.classname);
		}
		this.isInteractive = o.isInteractive || this.isInteractive;
		this.starCount = o.starCount || this.starCount;
		this.style = o.style || this.style;
	};
	this.reset = function(){
		if(this.isInteractive){
			$(this.dom).find("img").unbind("mouseenter").unbind("mouseleave").unbind("click");
		}
		$(this.dom).empty();
	};
	this._calcStarState = function(i,r){
		var st = 'empty',as = r-i;
		if(i<r){
			if(as<0.25){
				st = 'empty';
			}else if(as<=0.75){
				st = 'half';
			}else{
				st = 'full';
			}
		}
		return st;
	};
	this.render = function(d){
		this.reset();
		d = d || 0;
		d = parseInt(d);
		var stars = $(document.createElement("div")), as = ratingToString(d), st = '', img=null, act = this.isInteractive;
		$(stars).addClass("starbox");
		if(act){
			$(stars).addClass("starbox-interactive");
		}
		for(var i=0; i<5; i+=1){
			st = this._calcStarState(i,d);
			img = $("<img src='"+this.images[st]+"' class='"+this.classname[st]+"' "+((this.style)?"style='"+this.style+"'":"")+" border='0'></img>");
			if(act){
				$(img).mouseenter((function(t,ind){
					return function(){
						$(t.dom).find("img").each(function(i,e){
							var st = t._calcStarState(i,ind);
							$(e).attr("src",t.images[st]).attr("class",t.classname[st]);
						});
						t.publish({event:"mousenter",value : {index : ind,elem : $(this)}});
					};
				})(this,(i+1)));
				$(img).mouseleave((function(t,ind,rating){
					return function(){
						$(t.dom).find("img").each(function(i,e){
							var st = t._calcStarState(i,rating);
							$(e).attr("src",t.images[st]).attr("class",t.classname[st]);
						});
						t.publish({event:"mouseleave",value : {index : ind,elem : $(this)}});
					};
				})(this,(i+1),d));
				$(img).click((function(t,ind){
					return function(){
						t.publish({event:"click",value : {index : ind,elem : $(this)}});
					};
				})(this,(i+1)));
			}
			$(stars).append(img);
		}
		$(this.dom).append($(stars));
	};
	this._constructor();
},{ /* statics used for default values */
	images : {
		full : "images/star2.png",
		half : "images/star15.png",
		empty : "images/star1.png",
		active : "images/star2.png"
	},
	classname : {
		full : 'starbox_full',
		half : 'starbox_half',
		empty : 'starbox_empty',
		active : 'starbox_active'
	}
});
appdb.views.RatingChart = appdb.ExtendClass(appdb.View,"appdb.views.RatingChart",function(o){
    this.RatingColors = ["#FF6F31","#FF9F02","#FFCF02","#A4CC02","#88B131"];
    this.RatingBarStyle = {"height":"21px"};
    this._maxBarWidthValue=0;
    this._maxVoteValue = 0;
    this._getMaxValue = function(d){
        var i, len = d.length, max=0, v;
        for(i=0; i<len; i+=1){
			v = parseInt(d[i].votes);
            if(v>max){
                max = parseInt(d[i].votes);
            }
        }
        return max;
    };
    this._createBar = function(val,color){
        var div = $(document.createElement("div")), bar = $(document.createElement("div")), v = $(document.createElement("div")), w="100",max = this._maxVoteValue;
        w = (this._maxBarWidthValue * (val/max));
        w = (w<1)?1:w;
        w = Math.ceil(w);
        $(bar).addClass("ratingchart-bar").css($.extend({"background-color":color,width: w+"%"},this.RatingBarStyle));
        $(div).append($(bar));
        $(v).addClass("ratingchart-value").html(val);
        $(div).append($(v))
        $(div).addClass("ratingchart-barcontainer");
        return $(div);
    };
    this._createRow = function(d,unrated){
		unrated = unrated || false; // Indicates that there is no rating given at all, if non given it renders no value
        var tr = $(document.createElement("tr")); //returning row
        var tdl = $(document.createElement("td")); //display star count
        var tdc = $(document.createElement("td")); //display bar
		
		//Create stars on the left of the row
        var stars = "<span class='ratingchart-rating' title='Rated with "+d.value+((d.value>1)?" stars":" star")+"'>";
		for(var i=0; i<d.value; i+=1){
			stars += "<img src='images/star2.png' border='0'></img>";
		}
		stars += "</span>";
		$(tdl).addClass("ratingchart-rating-column").html(stars);
        $(tr).append($(tdl));
		
        //Append the colored bar
		$(tdc).append((unrated)?$("<div class='ratingchart-rating-unrated'></span>").css(this.RatingBarStyle):this._createBar(d.votes, this.RatingColors[d.value-1]));
        $(tdc).css({"border-left":"1px solid black"});
        $(tr).append($(tdc));
        $(tr).addClass("ratingchart-bar-column");
        return $(tr);
    };
    this.render = function(d){
        this.reset();
        var row, i, len = d.length, table = $(document.createElement("table")), tbody = $(document.createElement("tbody")), isunrated = false;
        if(d && d.length>0){
            d = d.reverse();
        }
		this._maxVoteValue=this._getMaxValue(d);
		isunrated = (this._maxVoteValue===0)?true:false;
        $(table).attr("cellspacing","0").attr("cellpadding","0").css({width:$(this.dom).css("width"),"padding":"10px"});
        $(table).append($(tbody));
		$(this.dom).addClass("ratingchart").append($(table));
        //Calc maximimum width of bar
        var tval = (100 - parseInt(4 * (''+this._maxVoteValue).length))-2;
        var w = ((tval<1)?15:tval);
        this._maxBarWidthValue = w;
		//In case of no rating given, it display a descriptive message
		if(isunrated){
			$(tbody).append("<tr><td></td><td></td><th class='ratingchart-unrated' rowspan='"+(len+len)+"'><i>no votes yet</i></th></tr>");
		}
		for(i=0; i<len; i+=1){
            row = $(this._createRow(d[i],isunrated));
            $(tbody).append(row);
            if(i<(len-1)){
                $(tbody).append("<tr><td></td><td class='ratingchart-seperator' ></td></tr>");
            }
        }
    };
});
appdb.views.ErrorHandler = function(){
    var dlg = null;
    this.createDetails = function(d){
        var i,res = "<ul style='list-style:none;border-style:solid;border-width:2px;border-color:gray;padding:5px;height:250px;overflow:auto;'>";
        if($.isPlainObject(d)){
            for(i in d){
                res+="<li><b>"+i+"</b> : " + d[i] + "</li>";
            }
            res+="</ul>";
        }else if($.isArray(d)){
            for(i=0; i<d.length; i+=1){
                res+="<li>"+d[i]+"</li>";
            }
            res+="</ul>";
        }else{
            res = d;
        }
        return res;
    };
    this.handle = function(err){
        this.destroy();
        var body = $("<table style='width:600px;'><tbody></tbody></table>");
        var descr = $("<tr></tr>");
        var detailsCell = $(document.createElement("td"));
        var detailsRow = $(document.createElement("tr"));
        var detailsSource = $(document.createElement("div"));
        var a = $(document.createElement("a"));
        $(descr).append("<td>"+(err.description || "<i>No description</i>")+"<td>");
        $(body).append($(descr));
        if(err.source){
            $(descr).append("<tr><tr>")
            $(detailsSource).html(this.createDetails(err.source));
            $(detailsSource).css({width:"99%"});
            $(detailsSource).hide();
            $(a).attr("href","#").attr("alt","Click to view source error").text("details").click(function(){
                if($(detailsSource).css("display")==="none"){
                    $(detailsSource).css("display","block");
                }else{
                    $(detailsSource).css("display","none");
                }
            });
            $(a).css("float","right");
            $(detailsCell).append($(a));
            $(detailsRow).append($(detailsCell));
            $(body).append($(detailsRow));
            $(body).append($(detailsSource));
        }

        dlg = new dijit.Dialog({
            title: err.status || "Error",
            content : $(body)[0]
        });
        dlg.show();
    };
    this.destroy = function(){
        if(dlg){
            dlg.destroyRecursive(false);
        }
    };
};

appdb.views.TagOptions= appdb.ExtendClass(appdb.View,"appdb.views.TagOptions",function(o){
    this._options = null;
    this.ErrorHandler = new appdb.views.ErrorHandler();
	this.reset = function(){
		if(this.tagcombo){
			this.tagcombo.destroyRecursive(false);
		}
		$(this.dom).empty();
	};
    this._setPolicy = function(appid,policy,prevpolicy){
        var m = new appdb.model.ApplicationTagPolicy();
        m.subscribe({event:"insert",callback: function(v){
                this.render({id:appid,tagPolicy:policy, owner:"internal"},false);
        },caller:this});
        m.subscribe({event:"error",callback:function(e){
                this.ErrorHandler.handle({status:"Could not update tag policy",description:(e.error||e.description),source : null});
                this.render({id:appid,tagPolicy:prevpolicy});
        },caller:this});
        m.insert({id:appid,"policy":policy});
    };
    this._renderDialog = function(appid,policy){
            policy = parseInt(policy) || 0;
            var res = document.createElement("div"), title = document.createElement("div"), form = document.createElement("form"),commit = document.createElement("a");
            $(title).addClass("tagoptions-title").text("Allow tag insertion by:");
            $(form).attr("id","tagpolicy");
            $(form).append("<input type='radio' name='policy' value='0' " +((policy===0)?"CHECKED":"")+ ">Only me</input><div></div>");
            $(form).append("<input type='radio' name='policy' value='1' " +((policy===1)?"CHECKED":"")+ ">Related contacts</input><div></div>");
            $(form).append("<input type='radio' name='policy' value='2' " +((policy===2)?"CHECKED":"")+ ">Everyone</input><div></div>");
            $(form).find("input").click((function(_this){
                return function(){
                    _this._setPolicy(appid,$(this).val(),policy);
                };
            })(this,appid));
            $(res).attr("id","tagpolicydialog").addClass("tagoptions-policy");
            $(res).append($(title));
            $(res).append($(form));
            return res;
        };
	this.render = function(d,reset){
            reset = reset || true;
            if(reset===true){
                this.reset();
            }
            if(d.owner==="internal"){

            }else if((userID!==null && (userID===parseInt(d.owner.id) || userRole===5 ))===false){
                return;
            }
            var tagButton = document.createElement("span");
			$(tagButton).addClass("taglist-add").append("<span>options</span>");
            $(tagButton).attr("id","tagoptionsbutton");
            var dialog = this._renderDialog(d.id,d.tagPolicy);
            $(tagButton).click(function(){
                setTimeout(function(){
                    var d =  new dijit.TooltipDialog({content : $(dialog)[0]});
                    dijit.popup.open({
                        parent : dojo.byId("tagoptionsbutton"),
                        popup: d,
                        around : dojo.byId("tagoptionsbutton"),
                        orient: {'BL':'TL','BR':'TR'}
                    });
                },10);                
            });
            $(this.dom).append($(tagButton));
	};
});
appdb.views.TagList = appdb.ExtendClass(appdb.View,"appdb.views.TagList", function(o){
	this._totalCount = -1;
    this._tagOptions = null;
	this._toggler = document.createElement("a");
	this._adder = document.createElement("li");
	this.ErrorHandler = new appdb.views.ErrorHandler();
	this.reset = function(){
		$(this._toggler).unbind("click").empty();
		$(this._adder).empty();
		this._toggler = document.createElement("a");
		$(this._toggler).addClass("taglist-toggler").attr("title","Click to view all associated tags").text("more...").click((function(t){
			return function(){
				t._toggleList();
				if(t._isExpanded()){
					$(this).attr("title","Click to collapse the tag list").text("...less");
				}else{
					$(this).attr("title","Click to view all associated tags").text("more...");
				}
			};
		})(this));
        if(this._tagOptions){
            this._tagOptions.destroy();
        }
        $(this.dom).empty();
	};
	this._refreshTagCloud = function(){
		appdb.model.Tags.get();
	};
	this._deleteTag = function(appid,tag,elem){
		tag = encodeURI(tag);
		var model = new appdb.model.ApplicationTags();
		model.subscribe({event: 'beforeremove',callback:function(d){
			$(elem).addClass("taglist-tag-removing");
			$(elem).find(".taglist-editable").append("<div style='display:inline;' id='taglist-add-loader'><img src='images/ajax-loader-small.gif' alt='' title='removing tag' width='12px'> </img><span >removing...</span></div>");
		},caller:this}).subscribe({event: 'remove',callback:function(d){
			$(elem).remove();
            var tgs = $(this.dom).find("li.taglist-tag");
            if(tgs.length===0){
               $(this.dom).find('.taglist-notags').css({"display":"inline-block"});
            }
			$(tgs).each(function(index){
				if(index<appdb.views.TagList.maxVisibleTags){
					$(this).removeClass("taglist-tag-hide");
				}else{
					$(this).addClass("taglist-tag-hide");
				}
			});
			if($(this.dom).find("li.taglist-tag-hide").length>0){
				$(this._toggler).css("display","inline-block").text("more...");
			}else{
				$(this._toggler).css("display","none");
			}
			this._refreshTagCloud();
		},caller:this}).subscribe({event:'error',callback:function(d){
			$(elem).removeClass("taglist-tag-removing");
			$(elem).remove("img");
			$(elem).find("#taglist-add-loader").remove();
			this.ErrorHandler.handle({status:"Tag deletion error",description:d.error || "Could not delete the selected tag",source : (d.error)?null:d});
		},caller:this});
		model.remove({id:appid,"tag":tag});
	};
	this._addTag = function(appid,tag,ownerid){
		var m = new appdb.model.ApplicationTags();
		m.subscribe({event:"beforeinsert",callback:function(){
			$(this.dom).find("#taglist-add-edit").css("display","none");
			$(this.dom).find("#taglist-add-edit").parent().append("<div style='display:inline;' id='taglist-add-loader'><img src='images/ajax-loader-small.gif' alt='' title='adding tag' width='12px'> </img><span >adding...</span></div>");
		},caller:this});
		m.subscribe({event:"error",callback:function(e){
			$(this.dom).find("#taglist-add-loader").remove();
			$(this.dom).find("#taglist-add-edit").css("display","inline-block");
			this.ErrorHandler.handle({status:"Tag insertion error",description:(e.error||e.description),source : null});
		},caller:this});
		m.subscribe({event:"insert",callback:function(){
			$(this.dom).find("#taglist-add-loader").remove();
			this._closeAdd();
			setTimeout((function(_this){
				return function(){
                    tag = tag.replace(/\ /,".");
					m.destroy();
                    $(_this.dom).find('.taglist-notags').css({"display":"none"});
                    var uitag = _this._createTag({submitterID:ownerid,val:(function(ttag){return function(){return ttag;};})(tag)},'',true,appid);
                    $(_this.dom).find("ul.taglist-list").first().append(uitag);
				};
			})(this),50);
		},caller:this});
		m.insert({id:appid,"tag":tag});
	};
	this._createTag = function(t,cls,canRemove,appid){
		canRemove = canRemove || false;
        if(canRemove === false && userID!==null && t.submitterID && parseInt(t.submitterID)!=0){
            if(userID===parseInt(t.submitterID)){
                canRemove = true;
            }
        }
        var val = (t.val)?t.val():t;
		var res = document.createElement("li");
		var dec = document.createElement("div");
		var rem = document.createElement("div");
		var a = document.createElement("a");
		$(a).attr("title","Search with tag " + val).attr("href","#").click(function(){
			appdb.views.Main.showApplications({flt:'tag:'+val},{isBaseQuery:true,filterDisplay:'Search with tag '+val+'...',mainTitle : 'tag: '+val});
		}).text(val);
		
		if(cls){
			$(res).addClass(cls);
		}
        $(res).addClass("taglist-tag");
            if(parseInt(t.submitterID)===0){
            $(res).addClass("taglist-tag-system");
        }
		if(canRemove){
			$(rem).addClass("taglist-remove").addClass("taglist-remove-hide").attr("title","Remove tag " + val);
			$(rem).click((function(_this,tag,id,elem){
				return function(){
					_this._deleteTag(id,tag,elem);
				};
			})(this,val,appid,res));
            $(rem).append("<img alt='' src='/images/cancelicon.png' width='12' style='vertical-align:top;padding:0px;margin:0px;padding-right:2px;'></img>");
            $(dec).addClass("taglist-editable-hide").append($(a)).append($(rem));
            $(dec).hover(function(){
                $(dec).removeClass("taglist-editable-hide").addClass("taglist-editable");
            },function(){
                $(dec).removeClass("taglist-editable").addClass("taglist-editable-hide");
            });
			$(res).append($(dec));
		}else{
			$(res).append($('<div class="taglist-editable-hide"></div>').append($(a)).append("<img alt='' src='/images/cancelicon.png' width='12' style='visibility:hidden;vertical-align:top;padding:0px;margin:0px;padding-right:2px;'></img>"));
		}
		return res;
	};
	this._collapseList = function(){
		if(this.totalCount<=0){
			return;
		}
		$(this.dom).find(".taglist-tag").each(function(index,el){
			if(index<appdb.views.TagList.maxVisibleTags){
				return;
			}
			$(this).addClass("taglist-tag-hide");
		});	
	};
	this._expandList = function(){
		if(this.totalCount<=0){
			return;
		}
		$(this.dom).find(".taglist-tag").each(function(){
			$(this).removeClass("taglist-tag-hide");
		});
	};
	this._isExpanded = function(){
		return ($(this.dom).find(".taglist-tag-hide").length>0)?false:true;
	};
	this._toggleList = function(){
		if(this._isExpanded()){
			this._collapseList();
		}else{
			this._expandList();
		}
	};
	this._isEditable = function(d){
		d = d || {};
		var acts = [];
		if(d.permissions && d.permissions.action){
			if($.isArray(d.permissions.action)===false){
				d.permissions.action = [d.permissions.action];
			}
            acts = d.permissions.action;
		}
		if(acts.length>0){
			for(var i=0; i<acts.length; i+=1){
				if(acts[i].id==="24"){
					return true;
				}
			}
		}
		return false;
	};
	this._closeAdd = function(){
		var elem = $($(this._adder).find("#taglist-add-edit")[0]).parent();
		if($(this._adder).has("#taglist-add-edit")){
			var dj = dijit.byId("taglist-add-select");
			if(dj){
				dj.destroyRecursive(false);
			}
			$(elem).removeClass("taglist-add-edit").addClass("taglist-add");
			$(elem).find("#taglist-add-edit").remove();
			$(elem).find("#taglist-add").css("display","inline-block");
		}
		
	};
	this._renderAdd = function(data,elem,tgs){
		//cleaning
        var appid = data.id;
		if($(elem).has("#taglist-add-edit")){
			var dj = dijit.byId("taglist-add-select");
			if(dj){
				dj.destroyRecursive(false);
			}
			$(elem).find("#taglist-add-edit").empty();
		}
		//declare elements
		var i, ts = appdb.model.Tags.getLocalData().tag , len=ts.length, list = [];
		var doc = document, select = doc.createElement("input"), ok = doc.createElement("button"), cancel = doc.createElement("button"), res = doc.createElement("div");
		
		$(res).attr("id","taglist-add-edit");
		$(res).append($("<span></span>").append($(select))).append($("<span></span>").append($(cancel))).append($("<span></span>").append($(ok)));
		//set elements style
		$(select).addClass("taglist-add-select").attr("id","taglist-add-select");
		$(ok).addClass("taglist-add-ok").attr("disabled","disabled").attr("title","Submit new tag").append("<img src='images/yes_grey.png' alt='' width='10px'></img>");
		$(cancel).addClass("taglist-add-cancel").attr("title","Cancel").append("<img src='images/cancelicon.png' alt='' width='10px'></img>");

		//Transform tag json data for dojo itemfilereadstore
		for(i =0 ; i<len; i+=1){
			list[list.length] = {index:i,tag:ts[i].val()};
		}
		$(elem).removeClass("taglist-add").addClass("taglist-add-edit");
		$($(elem).find("#taglist-add").get(0)).css("display","none");
		$($(elem).find("#taglist-add-edit").get(0)).css("display","inline-block");
		$(elem).append(res);
		var _this = this;
		var sel = new dijit.form.ComboBox({
			store: new dojo.data.ItemFileReadStore({
				data: {label : "tag",id:"tag",items:list}
			}),
			searchAttr : "tag",
			required:false,
            onChange : function(val){
                var v =val.toLowerCase();
                var vlst = [];
                $(_this.dom).find("li.taglist-tag").each(function(){
                    vlst[vlst.length] = $(this).text().toLowerCase();
                });
                var i , len = vlst.length, found = false;
				if($.trim(v)!==''){
                    for(i=0; i<len; i+=1){
                        if(v==vlst[i]){
                            found = true;
                            break;
                        }
                    }
                }
                if(found || $.trim(v)==''){
                    $(ok).attr("disabled","disabled");
                    $($(ok).find("img").get(0)).attr("src",'images/yes_grey.png').attr("title","Submit new tag");// alt='' width='10px'></img>");
                    return true;
                }
                $(ok).removeAttr("disabled");
                $($(ok).find("img").get(0)).attr("src","images/yes.png").attr("title","Submit new tag");// alt='' width='10px'></img>");
                return true;
            },
            onKeyUp : function(e){
                var v = sel.attr("value").toLowerCase();
                var vlst = [];
                $(_this.dom).find("li.taglist-tag").each(function(){
                    vlst[vlst.length] = $(this).text().toLowerCase();
                });
                var i , len = vlst.length, found = false;
				if($.trim(v)!==''){
                    for(i=0; i<len; i+=1){
                        if(v==vlst[i]){
                            found = true;
                            break;
                        }
                    }
                }
                if(found || $.trim(v)==''){
                    $(ok).attr("disabled","disabled");
                    $($(ok).find("img").get(0)).attr("src",'images/yes_grey.png').attr("title","Submit new tag");// alt='' width='10px'></img>");
                    return true;
                }
                $(ok).removeAttr("disabled");
                $($(ok).find("img").get(0)).attr("src","images/yes.png").attr("title","Submit new tag");// alt='' width='10px'></img>");
                return true;
            }
		},$(elem).find("#taglist-add-select").get(0));
		setTimeout(function(){
			sel.focus();
		},100);
		//setup actions
		$(ok).click((function(_this,_appid){
			return function(){
				_this._addTag(_appid,dijit.byId("taglist-add-select").attr('value'),data.owner.id);
				return false;
			};
		})(this,appid));
		$(cancel).click((function(_this){return function(){_this._closeAdd.apply(_this);return false;};})(this));
		
	};
	this.render = function(d,isAdded){
		this.reset();
		d = d || {};
        isAdded = isAdded || false;
		var tagoptions = null, cc = $("<table cellpadding='0' cellspacing='0' style='padding:0px;margin:0px;'><tbody><tr><td class='taglist-options-cell'></td><td class='taglist-list-cell'></td></tr></tbody></table>"),c = document.createElement("ul"), i, len, t = d.tag || '', isEditable = this._isEditable(d), max = appdb.views.TagList.maxVisibleTags;
        if($.isArray(t)===false){
            t = ($.trim(t)==='')?[]:[t];
        }
		len = t.length;
		$(c).addClass("taglist-list");
		this._totalCount = len;
		$(this.dom).addClass("taglist");
        tagoptions = document.createElement("span");
        if(userID===null || (userID!==null && isEditable===true)){
			var sp = document.createElement("span");
			$(sp).attr("id","taglist-add").attr("title","Click to add a new tag").text("add");
            $(this._adder).addClass("taglist-add").append(sp).click((function(_this,id,canEdit){
                return function(){
                        if(canEdit){
                            if($(this).find("#taglist-add-edit").length===0){
                                _this._renderAdd(d,$(this),t);
                            }
                        }else{
                            setTimeout(function(){
                               var c = $("<div style='width:450px;'>If you wish to add a new tag, please <a class='login' href='#' >login</a> first using your EGI SSO account. If you don't have an EGI SSO account you can acquire one <a href='https://www.egi.eu/sso/' target='_blank'>here</a></div>");
                               $($(c).find(".login").get(0)).click(function(){
                                    dijit.popup.close(d);
                                    login();
                                });
                               var d =  new dijit.TooltipDialog({content : $(c)[0]});
                               dijit.popup.open({
                                    parent : dojo.byId("taglist-add"),
                                    popup: d,
                                    around : dojo.byId("taglist-add"),
                                    orient: {'BL':'TL','BR':'TR'}
                                });
                                setTimeout(function(){
                                    dijit.popup.close(d);
                                },7000);
                            },10);
                        }
                    };
            })(this,d.id,isEditable));
            $(c).append(this._adder);
        }
		//Sort tags, set forst the system tags then the user tags
		if(len>1){
			var systemTags = [], userTags = [];
			for(i=0; i<len; i+=1){
					if(t[i].submitterID==0){
						systemTags[systemTags.length] = t[i];
					}else{
						userTags[userTags.length] = t[i];
					}
			}
			systemTags.sort(function(a,b){
				var na = a.val().toLowerCase(), nb = b.val().toLowerCase();
				if ( na < nb ) return -1;
				if ( na > nb ) return 1;
				return 0;
			});
			userTags.sort(function(a,b){
				var na = a.val().toLowerCase(), nb = b.val().toLowerCase();
				if ( na < nb ) return -1;
				if ( na > nb ) return 1;
				return 0;
			});
			t = systemTags.concat(userTags);
		}
		//end of sorting

        for(i=0; i<len; i+=1){
            $(c).append(this._createTag(t[i],((i<max)?'':"taglist-tag-hide"),(isEditable && (parseInt(t[i].submitterID)!==0)),d.id));
        }
        if(len>max){
            $(c).append(this._toggler);
            $(this._toggler).css("display","inline-block");
        }
        
        if(len==0){
            $(c).append("<li class='taglist-notags'><span >"+appdb.views.TagList.emptyMessage+"</span></li>");
        }
        $(cc).find(".taglist-list-cell").append(c);
        $(this.dom).append(cc);
        $(cc).find(".taglist-options-cell").append($(tagoptions));
        if(userID!==null && (userID===parseInt(d.owner.id) || userRole===5 )){
            this._tagOptions = new appdb.views.TagOptions({container : $(tagoptions)});
            this._tagOptions.render(d);
        }
	};
},{
	maxVisibleTags : 15,
	emptyMessage : "No tags available</span>"
});

appdb.views.TagCloud = appdb.ExtendClass(appdb.View,"appdb.views.TagCloud", function(o){
	this._tagControl = $.fn.tagcloud; //backup
	this._tagsort = $.fn.tsort;//backup
	this.render = function(d){
		this.reset();
		d = d || {};
		var h=document.createElement("ul"), i, len, t = d.tag || [] ,v;
		len = t.length;
		$(h).css({"width": "95%","height":"200px","position":"static"});
		for(i=0; i<len; i+=1){
			v = t[i].val();
			$(h).append("<li value='"+t[i].count+"'><a href='#' onmouseover='$(this).data(\"bckcolor\",$(this).css(\"color\"));$(this).css({color:\"#D96B00\"});' onmouseout='$(this).css({color:\"\"+$(this).data(\"bckcolor\")});' title='click to search for "+v+"' onclick='appdb.views.Main.showApplications({flt:\"tag:"+v+"\"},{isBaseQuery:true,filterDisplay:\"Search with tag "+v+"...\",mainTitle : \"tag: "+v+"\"});' >"+v+" </a></li>");
		}
		$(this.dom).append($(h));
		var c = $($(this.dom).find("ul").get(0));
		if(typeof c.tagcloud === "undefined"){
			c.tagcloud = this._tagControl;
		}
		c.tagcloud({type:"list",sizemin:10,colormin:"727070",colormax:"727FFF"});
		var ts = c.find("li");
		if(typeof ts.tsort === "undefined"){
			ts.tsort = this._tagsort;
		}
		$($(this.dom).find("ul")[0]).css("width","95%");
		ts.tsort();
	};
});
appdb.views.NewsFeed = appdb.ExtendClass(appdb.View,"appdb.views.NewsFeed",function(o){
    this.newsImage = appdb.views.NewsFeed.icon;
    this.customizable = appdb.views.NewsFeed.customizable || false;
    this.customDialog = null;
    this.feed = {
       type : "app",
       name : "",
       title : "",
       actions:[
           {value:"insert",name:"New applications",selected:true},
           {value:"update",name:"Application updates",selected:true},
           {value:"insertcmm",name:"New comments",selected:false},
           {value:"insertcnt",name:"New contacts",selected:false}],
       flt : "",
       format :  appdb.views.NewsFeed.format
    };
    this._constructor = function(){
        if(o.image){
            this.newsImage = o.image;
        }
        if(typeof o.customizable === "boolean"){
            this.customizable = (Boolean(o.customizable) && true);
        }
        this.feed = $.extend(o.feed,this.feed);
    };
    this._createFeed = function(){
        var domain = appdb.config.endpoint.base, q = "", feed = this.feed, f,actions = [];
        if(domain.substr(0,6)==="https:"){
            domain = "http:" + domain.substr(6,domain.length);
        }
        domain = domain + "news/" +(feed.format || "atom");
        if(typeof feed.flt === "string"){
            f = appdb.utils.base64.encode(feed.flt);
        }
        for(var i=0; i<this.feed.actions.length; i+=1){
            if(this.feed.actions[i].selected===true){
                actions[actions.length] = this.feed.actions[i].value;
            }
        }
        actions = actions.join(",");
        q = ((feed.type)?"t="+feed.type+"&":"") + ((feed.name)?"n="+feed.name+"&":"") + ((f)?"f="+f+"&":"") + ((actions!=='')?"a="+actions+"&":"") + ((feed.title)?"title="+appdb.utils.base64.encode(feed.title):"") ;
        if(q.length>0){
            if(q[q.length-1]==="&"){
                q =q.substr(0,q.length-1);
            }
            domain = domain + "?" + q;
        }
        return domain;
    };
	this._renderCustomFeed = function(v){
		var i, doc = document, res = doc.createElement("div"), desc = doc.createElement("span"), title = doc.createElement("span"),
			format=doc.createElement("span"), actions=doc.createElement("span"), commands=doc.createElement("span");
		$(res).addClass("customfeed");
		$(desc).addClass("description");
		$(title).append("<span class='title'>Title:</span>").
            append("<input type='text'  />").
            addClass("title");
        (new dijit.form.TextBox({
            value : this.feed.title,
            "class" : "title",
            onChange : (function(_this){
                    return function(val){
                        _this.feed.title = val;
                        _this._setFeedUrl(_this._createFeed());
                    };
                })(this)
            },
            $(title).find("input")[0]));

        $(format).append("<span class='title'>Format:</span>").
			append("<span class='radiooption'><input type='radio' name='feedformat' value='atom'  checked='checked' /><span>atom</span></span>").
            append("<span class='radiooption'><input type='radio' name='feedformat' value='rss'  /><span>rss</span></span>").
			addClass("format");
        $(format).find("span.radiooption > input").each((function(_this){
            return function(index,elem){
                (new dijit.form.RadioButton({
                    checked : (index===0),
                    onChange : (function(e){
                        return function(v){
                            if(Boolean(v)===true){
                                _this.feed.format = $(e).val();
                                _this._setFeedUrl(_this._createFeed());
                            }
                        };
                    })(elem)
                },$(this)[0]));
            };
        })(this));
        
		$(actions).append("<span class='title'>News about:</span>").addClass("actions");
        for(i=0; i<this.feed.actions.length; i+=1){
            $(actions).append("<span class='checkoption'><input type='checkbox' value='"+this.feed.actions[i].value+"' checked  /><span>"+this.feed.actions[i].name+"</span></span>")
        }
        $(actions).find("span.checkoption > input").each((function(_this){
            return function(index,elem){
                (new dijit.form.CheckBox({
                    checked : _this.feed.actions[index].selected,
                    onChange : (function(e){
                        return function(v){
                           var i , found = -1, acts = _this.feed.actions, name = $(e).val(), val = Boolean(v);
                           for(i=0; i<acts.length; i+=1){
                               if(acts[i].value===name){
                                   found = i;
                                   break;
                               }
                           }
                           if(found>=0){
                               acts[found].selected = val;
                           }
                           _this.feed.actions = acts;
                           _this._setFeedUrl(_this._createFeed());
                        };
                    })(elem)
                },$(this)[0]));
            };
        })(this));

		$(commands).
			append("<span class='command viewfeed' ><a href='"+this._createFeed()+"' alt='' title='View news feed in new window.' target='_blank' >View feed</a></span>").
			addClass("commands");
        $(res).append(desc).append(title).append(format).append(actions).append(commands);
		return res;
	};
    this._setFeedUrl = function(u){
        var a = $(this.dom).find("a.atomfeed-link");
        if(a.length>0){
            a = $(a[0]);
            $(a).attr("href",u);
        }
        if(this.customizable){
            $($(this.customDialog).find(".viewfeed > a")[0]).attr("href",u);
        }
    };
    this.render = function(d){
        this.reset();
        if(typeof d === "string"){
            d = {flt : d};
        }
        this.feed = $.extend(this.feed,d);
        var u = this._createFeed();
        var div = document.createElement("div"), a = document.createElement("a"), a2 = document.createElement("a"), span = document.createElement("span"), img = document.createElement("img");
        $(span).append("&#9662;");
        if(this.customizable){
            $(a2).attr("target","_blank").attr("title","Customize the news feed").addClass("atomfeed-select").append(span);
           this.customDialog = this._renderCustomFeed();
           $(this.customDialog).click(function(event) {
                var src = event.srcElement?event.srcElement:event.target;
                if(src && src.tagName.toLowerCase()==="a"){
                    return true;
                }
                return false;
            });
            $(a2).click((function(_this,parent){
                return function(){
                    setTimeout(function(){
                        var d =  new dijit.TooltipDialog({content : $(_this.customDialog)[0]});
                        dijit.popup.open({
                            parent : parent,// dojo.byId("tagoptionsbutton"),
                            popup: d,
                            around : parent,//dojo.byId("tagoptionsbutton"),
                            orient: {'BR':'TR'}
                        });
                    },10);
                    return false;
                };})(this,$(a2)[0]));
        }
        $(a).attr("target","_blank").attr("href",u).attr("title","Open the news feed for the listed items").addClass("atomfeed-link");
        $(img).attr("src",this.newsImage).attr("alt","").attr("border","0");
        $(a).append(img);
        $(div).append(a).addClass("atomfeed");
        if(this.customizable){
            $(div).append(a2).addClass("customizable");
        }
        $(this.dom).append(div);
    };
    this._constructor();
},{
    icon : "images/atom.png",
    format : "atom"
});
appdb.views.ApplicationUrls = appdb.ExtendClass(appdb.View,"appdb.views.ApplicationUrls",function(o){
	this._seperator = appdb.views.ApplicationUrls.seperator;
	this._data = [];
	this._currentPopup = null;
	this._constructor = function(){
		this._seperator = o.seperator || this._seperator;
	};
	this.reset = function(){
		$(this.dom).find("span > a").each(function(){
			$(this).unbind("click");
		});
		$(this.dom).empty();
	};
	this._showUrlList = function(elem,data){
		if(this._currentPopup!==null){
			this._currentPopup.cancel();
			dijit.popup.close(this._currentPopup);
			this._currentPopup.destroyRecursive(false);
		}
		this._currentPopup =  new dijit.TooltipDialog({content : $(data)[0]});
		dijit.popup.open({
			parent : elem,
			popup: this._currentPopup,
			around : elem,
			orient: {'BR':'TR','BL':'TL'}
		});
	};
	this._renderListHtml = function(data){
		var i, val, sval ,res = "";
		for(i=0; i<data.length; i+=1){
			if(typeof data[i].val === "undefined"){
				continue;
			}
			val = data[i].val();
			sval = val;
			if(sval.length>30){
				sval = sval.slice(0,27) + "...";
			}
			res += "<li><a href='"+val+"' target='_blank' title='Click to open link in new window\n "+val+"'>"+(data[i].title || sval)+"</a></li>";
		}
		res = "<div class='urllist'><ul>" + res +"</ul></div>";
		return res;
	};
	this._renderListItem = function(name,data){
		var htmllist, span = document.createElement("span"),a = document.createElement("a"), arrow = document.createElement("span");
		$(span).addClass("urlitem");
		$(arrow).addClass("urllistarrow").append("&#9660;");
		$(a).attr("href","#").attr("title","There are " + data.length + " " + name + " urls. Click to view them.").text(name + " (" + data.length + ")");
		htmllist = this._renderListHtml(data);
		$(a).click((function(_this,elem,html){
			return function(){
				_this._showUrlList(elem,html);
				return false;
			};
		})(this,$(arrow)[0],htmllist));
		$(a).append(arrow);
		$(span).append(a);
		return span;
	};
	this._renderItem = function(data){
		var span = document.createElement("span"),a = document.createElement("a");
		$(span).addClass("urlitem");
		$(a).attr("href",data.val()).attr("target","_blank").attr("title",data.val()).text(data.type);
		$(span).append(a);
		return span;
	};
	this.render = function(d){
		this.reset();
		this._data = d;
		var i, count = 0 , data = appdb.utils.GroupObjectList(d,"type");
		if(data == null){
			return;
		}else{
			for(i in data){
				count+=1;
			}
		}
		var container = document.createElement("div");
		$(container).addClass("applicationurls");
		for(i in data){
			count-=1;
			/*if(data[i].length==1 && data[i][0].val){
				$(container).append(this._renderItem(data[i][0]));
			}else{*/
				$(container).append(this._renderListItem(i,data[i]));
			/*}*/
			if(count>0){
				var sep =document.createElement("span");
				$(sep).addClass("urlseperator");
				$(sep).text(this._seperator);
				$(container).append(sep);
			}
		}
		$(this.dom).append(container);
	};
	this._constructor();
},{seperator : " | "});

appdb.views.ApplicationUrlsEditorItem = appdb.ExtendClass(appdb.View, "appdb.views.ApplicationUrlsEditorItem", function(o){
 this._data = {id:"",type:"",url:"",title:"",index:0};
 this._index = 0;
 this._types = null;
 this._title = null;
 this._url = null;
 this._remove = null;

 this.getIndex = function(){
  return this._data.index;
 };
 this.getData  = function(){
  var d = this._data;
  return {id : d.id, type : d.type, url : d.url, title:d.title};
  var res = {id:"",type:"",url:"",title:""};
  if(this._id !== ""){
   res.id = this._id;
  }
  if(this._types !== null){
   res.type = $.trim(this._types.attr("value"));
  }
  if(this._title !== null){
   res.title = $.trim(this._title.attr("value"));
  }
  if(this._url !== null){
   res.url = $.trim(this._url.attr("value"));
  }
  return res;
 };
 this.reset = function(){
  if(this._types !== null){
   this._types.destroyRecursive(false);
  }
  if(this._title !== null){
   this._title.destroyRecursive(false);
  }
  if(this._url !== null){
   this._url.destroyRecursive(false);
  }
  if(this._remove != null){
   this._remove.destroyRecursive(false);
  }
  $(this.dom).empty();
 };
 this.getValidUrlType = function(t){
  var v = appdb.views.ApplicationUrlsEditorItem.typestore.data.items;
  var item, len = v.length;
  for(var i=0; i<len; i+=1){
   item = v[i].name;
   if($.isArray(item)==false){
	item = [item];
	if(item==t){
	 return t;
	}
   }
  }
  return "";
 };
 this.render = function(d,index){
  this.reset();
  var data = d || {}, i = index|| 0, td1 = document.createElement("td"), td2 = document.createElement("td"), 
   td3 = document.createElement("td"), td4 = document.createElement("td"), a = document.createElement("a");
  if(typeof data.val === "undefined"){
   if(data.url){
	data.val = (function(durl){return function(){return durl};})(data.url);
   }else{
	data.val = function(){return "";};
   }
  }
  this._data = {id : data.id || "", type : data.type || "", url : data.val() || "", title : data.title || "", index: index || 0};
  $(td1).addClass("appurlitem").addClass("type").append("<span></span>");
  $(td2).addClass("appurlitem").addClass("url").append("<span></span>");
  $(td3).addClass("appurlitem").addClass("title").append("<span></span>");
  $(td4).addClass("appurlitem").addClass("remove").append("<span></span>");
  $(td4).find("span").append(a);
  $(a).attr("href","#").append("<img style='vertical-align: middle; padding-right: 3px;' alt='remove' border='0' src='/images/cancelicon.png' title='Remove url' />").click((function(_this){
   return function(){
	setTimeout(function(){_this.parent.removeItem(_this);},1);
   };
  })(this));
  $(this.dom).append(td1).append(td2).append(td3).append(td4);
  this._id = d.id || "";
  this._types = new dijit.form.FilteringSelect({
   name : "combo_url" + i,
   store : new dojo.data.ItemFileReadStore({data: {label:"name",id:"id",items:[{id:"Website", name : "Website"} , {id:"Documentation", name:"Documentation"}, {id:"Download", name:"Download"}, {id:"Support", name:"Support"}, {id:"Multimedia", name:"Multimedia"}, {id:"Try it", name: "Try it"}]}}),
   value : this.getValidUrlType(data.type),
   displayedValue : this.getValidUrlType(data.type),
   searchAttr : "name",
   placeHolder : "please select a type",
   autoComplete : true,
   required : true,
   onChange : (function(_this){
	return function(v){
	 if(v===""){
	  _this._data.type = "";
	 }else if(typeof v !== "undefined"){
	  var vv = appdb.views.ApplicationUrlsEditorItem.typestore.data.items[v].name;
	  _this._data.type = ($.isArray(vv)?vv[0]:vv);
	 }
	};
   })(this),
   onBlur : (function(_this){
	return function(v){
	 if(this.value===""){
	  _this._data.type = "";
	 }else{
	  var vv = appdb.views.ApplicationUrlsEditorItem.typestore.data.items[this.value].name;
	  _this._data.type = ($.isArray(vv)?vv[0]:vv);
	 }
	};
   })(this)
  },$(td1).find("span")[0]);
  setTimeout((function(_this){
   return function(){
	var v = _this._types.attr("value");
	if(v===""){
	 _this._data.type =  v;
	}else{
	 var vv = appdb.views.ApplicationUrlsEditorItem.typestore.data.items[v].name;
	_this._data.type = ($.isArray(vv)?vv[0]:vv);
	}
   };})(this),1);
  
  this._url = new dijit.form.ValidationTextBox({
   name : "url" + i,
   value : data.val(),
   placeHolder : "please provide a url",
   required : true,
   onChange : (function(_this){
	return function(v){
	 _this._data.url = v;
	};
   })(this)
  },$(td2).find("span")[0]);
  this._title = new dijit.form.ComboBox({
   name : "title_url" +i,
   value : data.title || "",
   store : new dojo.data.ItemFileReadStore(appdb.views.ApplicationUrlsEditorItem.titlestore),
   placeHolder : "please provide a title",
   searchAttr : "title",
   maxLength : 50,
   onChange :(function(_this){
	return function(v){
	 _this._data.title = v;
	}
   })(this)
  },$(td3).find("span")[0]);
  /*this._title = new dijit.form.ValidationTextBox({
   name : "title_url" + i,
   value : data.title || "",
   placeHolder: "please provide a title",
   maxLength : 50,
   onChange : (function(_this){
	return function(v){
	 _this._data.title = v;
	};
   })(this)
  },$(td3).find("span")[0]);*/
 };
} , {
 typestore : {data: {label:"name",id:"id",items:[{id:"Website", name : "Website"} , {id:"Documentation", name:"Documentation"}, {id:"Download", name:"Download"}, {id:"Support", name:"Support"}, {id:"Multimedia", name:"Multimedia"}, {id:"Try it", name: "Try it"}]}},
 titlestore : {data : {label:"title", id:"title", items:[]}}
});

appdb.views.ApplicationUrlsEditor = appdb.ExtendClass(appdb.View, "appdb.views.ApplicationUrlsEditor",function(o){
  this._initialData = [];
  this._data = [];
  this.getItemById = function(id){
   var i, len = this.subviews.length;
   for(i=0; i<len; i+=1){
	if(this.subviews[i].getData().id === id){
	 return this.subviews[i];
	}
   }
   return null;
  };
  this.canAddNew = function(){
   var i, len = this.subviews.length, item, d;
   for(i=0; i<len; i+=1){
	item = this.subviews[i];
	d = item.getData();
	if(d.type===""){
	 return item.dom;
	}
	if(d.url===""){
	 return item.dom;
	}
   }
   return true;
  };
  this._showAsInvalid = function(item){
   var prevColor = $(item).css("background-color") || "";
   $(item).animate({"opacity":"0.5","background-color":"red"},300,function(){setTimeout(function(){$(item).animate({"opacity":"1","background-color":prevColor},400);},10);});
  };
  this.getData = function(){
   var i, len = this.subviews.length, res = [];
   for(i=0; i<len; i+=1){
	res[res.length] = this.subviews[i].getData();
   }
   return res;
  };
  this.removeItem = function(item){
   this._data = this.getData();
   if(this._data.length > item.getIndex()){
	this._data.splice(item.getIndex(),1);
	this.render(this._data);
   }
  };
  this.addNew = function(){
   var canAdd = this.canAddNew();
   if(canAdd !== true){
	this._showAsInvalid(canAdd);
	return;
   }
   var tr = document.createElement("tr"), item, tbody = $(this.dom).find("table > tbody")[0];
   $(tbody).append(tr);
   item = new appdb.views.ApplicationUrlsEditorItem({container : tr, parent : this});
   item.render({},this.subviews.length);
   this.subviews[this.subviews.length] = item;
   this._data[this._data.length] = item.getData();
  };
  this.setupForm = function(frm){
   if($(frm).length==0){
	return false;
   }
   var i, len = this.subviews.length, item, inp;
   $(frm).remove("input[name^='url']");
   for(i=0; i<len; i+=1){
	item = this.subviews[i];
	inp = document.createElement("input");
	$(inp).attr("name","url"+i).attr("type","hidden").attr("value",JSON.stringify(item.getData()));
	$(frm).append(inp);
   }
   //$(frm).find(":input").each(function(index,elem){if($(elem).attr("name")=="documents" || $.trim($(elem).attr("name"))=='' ) return;console.log($(elem).attr("name") + " : " + $(elem).attr("value"));});
   return true;
  };
  this._setupHeader = function(){
   var thead = document.createElement("thead"), tr, th1, th2, th3;
   tr = document.createElement("tr");
   th1 = document.createElement("th");
   th2 = document.createElement("th");
   th3 = document.createElement("th");
   th4 = document.createElement("th");
   $(tr).append(th1).append(th2).append(th3).append(th4);
   $(thead).append(tr);

   $(th1).append("<span class='appurlsheader type'>" + appdb.views.ApplicationUrlsEditor.header.type + "</span>");
   $(th2).append("<span class='appurlsheader url'>" + appdb.views.ApplicationUrlsEditor.header.url + "</span>");
   $(th3).append("<span class='appurlsheader title'>" + appdb.views.ApplicationUrlsEditor.header.title + "</span>");
   $(th4).append("<span class='appurlsheader actions'></span>");
   return thead;
  };
  this._setupFooter = function(){
   var tfoot = document.createElement("tfoot"), tr = document.createElement("tr"), td = document.createElement("td");
   $(td).addClass("appurls-footer").attr("colspan","4").append("<span class='appurls-empty'>"+appdb.views.ApplicationUrlsEditor.footer.empty+"</span>").append("<span class='appurls-add'></span>");
   $(tr).append(td);
   $(tfoot).append(tr);
   new dijit.form.Button({
	label :"<i><b>add</b></i>",
	onClick : (function(_this){
	 return function(){
	  _this.addNew();
	 };
	})(this)
   },$(td).find("span.appurls-add")[0]);
   return tfoot;
  };
  
  this.render = function(d,sortby){
   this.render = this.onrender;
   if($.isArray(d)==false){
	d = [d];
   }
   this._initialData = d;
   this.render(d,sortby);
  };
  this.onrender = function(d,sortby){
   this.reset();
   var table = document.createElement("table"), tbody = document.createElement("tbody"),
   tr ,urls = ((sortby)?appdb.utils.SortObjectList({list:d, property:sortby}):d),i, len, item;
   $(table).addClass("appurls-editor").attr("cellspacing","0").attr("cellpadding","0").append(this._setupHeader()).append(tbody);
   $(this.dom).append(table);

   if($.isArray(urls)==false){
	urls = [urls];
   }
   this._data = urls;
   len = urls.length;
   for(i = 0; i<len; i+=1){
	tr = document.createElement("tr");
	$(tbody).append(tr);
	item = new appdb.views.ApplicationUrlsEditorItem({container:tr,parent : this});
	item.render(urls[i],i);
	this.subviews[this.subviews.length] = item;
   }
   $(table).append(this._setupFooter());
  };
  this.hasChanges = function(){
   //in case of item count change.
   if(this._initialData.length !== this._data.length){
	return true;
   }
   //If a new item is added
   if(this.getItemById("")!==null){
	return true;
   }
   var i, len = this._initialData.length;
   for(i=0; i<len; i+=1){
	var item = this.getItemById(this._initialData[i].id);
	//Item must be removed
	if(item === null){
	 return true;
	}
	var ditem = item.getData();
	if(typeof this._initialData[i].title === "undefined"){
	 this._initialData[i].title = "";
	}
	if(ditem.id != this._initialData[i].id || ditem.type != this._initialData[i].type || ditem.url != ((this._initialData[i].val)?this._initialData[i].val():"") || (ditem.title!=this._initialData[i].title) ){
	 return true;
	}
   }
   return false;
  };
  this._preloadUrlTitles = function(){
	var store = [], e = appdb.model.UsedAppUrlTitles.getLocalData();
	if (e && typeof e.title !== "undefined") {
		for(var i=0; i<e.title.length; i+=1){
			store[store.length] = {title : e.title[i].val()};
		}
	}
	appdb.views.ApplicationUrlsEditorItem.titlestore.data.items = store;
	appdb.model.UsedAppUrlTitles.get();
  };
  this._preloadUrlTitles();
},{
 header : {
  title : "Title<i style='color:gray;font-size:10px;font-weight:normal;'> (optional)</i>",
  type : "Type",
  url : "Url"
 },
 footer : {
  empty : "You can provide related urls by clicking the button on the right"
 }
});

