All pastes #2134941 Raw Edit

Someone

public text v1 · immutable
#2134941 ·published 2012-04-02 13:30 UTC
rendered paste body
/**
 * @constructor
 * @extend {aui.ui.ControlBase}
 * default width 300px
 * default height 100px
 */
aui.nvr2.ui.TimeTrack  = function(options){
    var me = this;
    
    this.options = {
		className: 'aui-nvr2-ui-TimeTrack'
	}
    this.options = aui.lang.merge(this.options, options || {});

    this.onSelect = new aui.lang.util.CustomEvent("onSelect", this);
    this.onDraw = new aui.lang.util.CustomEvent("onDraw", this);        // fire after load complete
    this.onCancelSync = new aui.lang.util.CustomEvent("onCancelSync", this);
		
    this.proto.superclass.constructor.call(this, this.options);
    
    this.setTimeSpan("hour");
}

aui.lang.Class.extend(aui.nvr2.ui.TimeTrack, aui.ui.ControlBase, {
    proto : aui.nvr2.ui.TimeTrack,

    /* DOM */
    pvtLoadingBlock : null,
    pvtSyncBlock : null,
    
    /* attributes */
    pvtTimeSpanValue : null,
    pvtSelectedCamera : null,
    //pvtSearchCamera : null,
    pvtTrackerWidth : null,
    
    pvtSelectTime : null,
    pvtSelectFile : null,
    pvtCurrentTime : null,

    /* tracker */
    pvtTracker : null,
    pvtTrackerHourBase : null,      // Hour track
    pvtTrackerDayBase : null,       // Day track

    /* DOM */
    pvtInfoBlock : null,

    /* UI */
    pvtCalendarDialog : null,
    
    prepareNode: function(nodeToAppend) {
        var me = this;
        nodeToAppend.className = this.options.className;
        
        nodeToAppend.innerHTML = [
            "<div class=title>",
                "<div class=titleleft>",
                    "<div class=cameralegend></div>",
                    "<div class=cameraid></div>",
                    "<div class=camerainfo></div>",
                "</div>",
                "<div class=titlecenter>",
                    "<div class=starttimelegend></div>",
                    "<div class=calendararea></div>",
                    "<div class=eventtypelegend></div>",
                    "<div class=eventarea></div>",
                "</div>",
                "<div class=titleright>",
                "</div>",
            "</div>",
            "<div class=content>",
                "<div class=moveleft></div>",
                "<div class=maintrack>",
                    "<div class=maintrack_title><div class=pointer></div></div>",
                    "<div class=maintrack_result></div>",
                    "<div class=maintrack_info>",
                        "<span class=time></span>",
                        "<span class=file></span>",
                        "<div class=scrollbase>",
                            "<div class=scroll>",
                                "<div class=scrollball></div>",
                            "</div>",
                            "<span class=timenow></span>",
                            "<span class=divider>/</span>",
                            "<span class=timemax></span>",
                        "</div>",
                    "</div>",
                "</div>",
                "<div class=moveright></div>",
            "</div>"
        ].join("");
        
        /* title */
        this.pvtTitle = nodeToAppend.firstChild;
        /* left */
        this.pvtTitleLeft = this.pvtTitle.firstChild;
        this.pvtCameraLegend = this.pvtTitleLeft.firstChild;
        this.pvtCameraLegend.innerText = LANG("ID_CAMERA")+":";
        this.pvtCameraID = this.pvtTitleLeft.childNodes[1];
        this.pvtCameraID.innerText = LANG("ID_NONE");
        this.pvtCameraInfo = this.pvtTitleLeft.childNodes[2];
        this.pvtCameraInfo.onclick = function(){
            me.pvtShowInfo(true, {
		        object:event.srcElement,
		        Model:me.pvtSelectedCamera.CameraModel,
		        ID:me.pvtSelectedCamera.NVR_CameraID,
		        Name:me.pvtSelectedCamera.CameraName,
		        IP:me.pvtSelectedCamera.CameraIP,
		        Channel:me.pvtSelectedCamera.ChannelNo,
		        FPS:me.pvtSelectedCamera.FPS,
		        Resolution:aui.nvr2.ui.CameraTreeView.Resolution[me.pvtSelectedCamera.Resolution] || "UNKNOWN("+me.pvtSelectedCamera.Resolution+")",
		        MediaSource:me.pvtSelectedCamera.NVRReference.Name
            });
        }
        /* info block */
        this.pvtInfoBlock = document.createElement("div");
        this.pvtInfoBlock.className = "infoBlock";
        this.pvtInfoBlock.innerHTML = [
            "<div class=line><span class=mediasource></span><span class=cameramodel></span></div>",
            "<div class=line><span class=infotitle></span><span class=infoname></span><span class=infotitle></span><span class=infoname></span></div>",
            "<div class=line><span class=infotitle></span><span class=infoname></span><span class=infotitle></span><span class=infoname></span></div>",
            "<div class=line><span class=infotitle></span><span class=infoname></span><span class=infotitle></span><span class=infoname></span></div>",
            "<div class=close></div>"
        ].join("");
        /* MediaSource */
        this.pvtInfoBlock.pvtMediaSource = this.pvtInfoBlock.firstChild.childNodes[0];
        /* model */
        this.pvtInfoBlock.pvtModel = this.pvtInfoBlock.firstChild.childNodes[1];
        /* ID */
        this.pvtInfoBlock.childNodes[1].childNodes[0].innerText = LANG("ID_CAMERAID");
        this.pvtInfoBlock.pvtID = this.pvtInfoBlock.childNodes[1].childNodes[1];
        /* Name */
        this.pvtInfoBlock.childNodes[1].childNodes[2].innerText = LANG("ID_INFO_NAME");
        this.pvtInfoBlock.pvtName = this.pvtInfoBlock.childNodes[1].childNodes[3];
        /* IP */
        this.pvtInfoBlock.childNodes[2].childNodes[0].innerText = LANG("ID_INFO_IP");
        this.pvtInfoBlock.pvtIP = this.pvtInfoBlock.childNodes[2].childNodes[1];
        /* Channel */
        this.pvtInfoBlock.childNodes[2].childNodes[2].innerText = LANG("ID_CHANNEL_NO");
        this.pvtInfoBlock.pvtChannel = this.pvtInfoBlock.childNodes[2].childNodes[3];
        /* FPS */
        this.pvtInfoBlock.childNodes[3].childNodes[0].innerText = LANG("ID_INFO_FPS");
        this.pvtInfoBlock.pvtFPS = this.pvtInfoBlock.childNodes[3].childNodes[1];
        /* Resolution */
        this.pvtInfoBlock.childNodes[3].childNodes[2].innerText = LANG("ID_INFO_RESOLUTION");
        this.pvtInfoBlock.pvtResolution = this.pvtInfoBlock.childNodes[3].childNodes[3];
        /* close */
        this.pvtInfoBlock.childNodes[4].onclick = function(){
            me.pvtShowInfo(false);
        }
        
        /* center */
        this.pvtTitleCenter = this.pvtTitle.childNodes[1];
        /* start time legend */
        this.pvtStartTimeLegend = this.pvtTitleCenter.firstChild;
        this.pvtStartTimeLegend.innerText = LANG("ID_STARTTIME");
        /* calendar area */
        var now = new Date();
        this.pvtCalendarArea = this.pvtTitleCenter.childNodes[1];
        this.pvtCalendarYearText = document.createElement("div");
        this.pvtCalendarYearText.className = "calendaryear";
        this.pvtCalendarArea.appendChild(this.pvtCalendarYearText);
        this.pvtCalendarYearText.innerText = aui.lang.Date.format(now, "%Y/%m/%d");
        this.pvtCalendarYearText.onclick = function(){
            me.pvtCalendarDialog.pvtCalendar.refresh();
            me.pvtCalendarDialog.showDialog({
                onResult : function(result){
                    if(result==aui.ui.Dialog.DialogResult.OK){
                        var date = me.pvtCalendarDialog.getSelectedDate();
                        if(!isNaN(date)) me.pvtCalendarYearText.innerText = aui.lang.Date.format(date, "%Y/%m/%d");
                    }
                }
            });
            me.pvtCalendarDialog.setSelectedDate(me.pvtCalendarYearText.innerText);
        }
        /* dropdown hour / time */
        this.pvtDropDownHour = new aui.ui.DropDownList({className:"calendarhour"});
        for(var i=0; i<24; i++)
            this.pvtDropDownHour.addOption(aui.text.String.padLeft(i, 2, "0"), i);
        this.pvtDropDownHour.render(this.pvtCalendarArea);
        this.pvtDropDownHour.setValue(now.getHours());

        this.pvtDropDownMinute = new aui.ui.DropDownList({className:"calendarminute"});
        for(var i=0; i<60; i+=10)
            this.pvtDropDownMinute.addOption(aui.text.String.padLeft(i, 2, "0"), i);
        this.pvtDropDownMinute.render(this.pvtCalendarArea);
        /* event legend */
        this.pvtEventTypeLegend = this.pvtTitleCenter.childNodes[2];
        this.pvtEventTypeLegend.innerText = LANG("ID_RECORDTYPE");
        /* event area */
        this.pvtEventArea = this.pvtTitleCenter.childNodes[3];
        /* event types */
        this.CHK_Schedule = new aui.nvr.ui.Checkbox({name:top.LANG("ID_SCHEDULE"), value:"Schedule", enabled:"true", classText:"schedule"});
        this.CHK_Schedule.render(this.pvtEventArea);
        this.CHK_DI = new aui.nvr.ui.Checkbox({name:top.LANG("ID_DI"), value:"DI", enabled:"true", classText:"DI"});
        this.CHK_DI.render(this.pvtEventArea);
        this.CHK_Motion = new aui.nvr.ui.Checkbox({name:top.LANG("ID_MOTION_AND_PIR"), value:"Motion", enabled:"true", classText:"motion"});
        this.CHK_Motion.render(this.pvtEventArea);
        this.CHK_Manual = new aui.nvr.ui.Checkbox({name:top.LANG("ID_MANUAL"), value:"Manual", enabled:"true", classText:"manual"});
        this.CHK_Manual.render(this.pvtEventArea);
        //this.CHK_PIR = new aui.nvr.ui.Checkbox({name:"PIR", value:"PIR", enabled:"true", classText:"manual"});
        //this.CHK_PIR.render(this.pvtEventArea);
        
        /* right */
        this.pvtTitleRight = this.pvtTitle.childNodes[2];
        this.BTN_1hour = new aui.nvr.ui.Button({className:"btn_1hour", alt:LANG("ID_HOUR_BASED")});
        this.BTN_1hour.render(this.pvtTitleRight);
        this.BTN_1hour.onclick.subscribe( function(){me.setTimeSpan("hour")} );
        this.BTN_1day = new aui.nvr.ui.Button({className:"btn_1day", alt:LANG("ID_DAY_BASED")});
        this.BTN_1day.render(this.pvtTitleRight);
        this.BTN_1day.onclick.subscribe( function(){me.setTimeSpan("day")} );
        this.BTN_search = document.createElement("input");
        this.BTN_search.className = "btn_search";
        this.BTN_search.type = "button";
        this.BTN_search.value = LANG("ID_SEARCH");
        this.BTN_search.onclick = function(){
            me.refreshSearch();
        }
        this.pvtTitleRight.appendChild(this.BTN_search);
        
        /* content */
        this.pvtContent = nodeToAppend.childNodes[1];
        this.pvtMoveLeft = this.pvtContent.firstChild
        this.pvtMoveRight = this.pvtContent.childNodes[2];
        this.pvtMainTrack = this.pvtContent.childNodes[1];
        this.pvtTrackerDayBase = new aui.nvr2.ui.TimeTrack.DayBase(this);
        this.pvtTrackerHourBase = new aui.nvr2.ui.TimeTrack.HourBase(this);
        /* pointer */
        this.pvtPointer = this.pvtMainTrack.firstChild.firstChild;
        /* track info */
        this.pvtMainTrackInfo = this.pvtMainTrack.childNodes[2];
        this.pvtMainTrackInfo_Time = this.pvtMainTrackInfo.firstChild;
        this.pvtMainTrackInfo_File = this.pvtMainTrackInfo.childNodes[1];
        this.pvtScrollBase = this.pvtMainTrackInfo.childNodes[2];
        this.pvtScrollBall = this.pvtScrollBase.firstChild.firstChild;
        this.pvtTimeNow = this.pvtScrollBase.childNodes[1];
        this.pvtTimeMax = this.pvtScrollBase.childNodes[3];
        /* previous / next event */
        this.pvtMoveLeft.onclick = function(){
            me.move(-1);
        }
        this.pvtMoveRight.onclick = function(){
            me.move(1);
        }
        
        /* dialog */
        this.pvtCalendarDialog = new aui.nvr2.ui.CalendarDialog({background:"dialog-bgcolor-black"});

		/* loading block */
		this.pvtLoadingBlock = document.createElement("div");
		this.pvtLoadingBlock.className = "loadingBlock";
		this.pvtLoadingBlock.innerText = LANG("ID_STATUS_LOADING")+"...";
		
		/* sync block */
		this.pvtSyncBlock = document.createElement("div");
		this.pvtSyncBlock.className = "loadingBlock";
		this.pvtSyncBlock.innerText = LANG("ID_DISABLED_IN_SYNCPLAYBACK");
		this.pvtSyncBlockButton = document.createElement("input");
		this.pvtSyncBlockButton.type = "button";
		this.pvtSyncBlockButton.value = LANG("ID_CANCEL");
		this.pvtSyncBlockButton.onclick = function(){
		    me.onCancelSync.fire();
		}
		this.pvtSyncBlock.appendChild(this.pvtSyncBlockButton);
		
		/* default disabled */
//        this.CHK_Schedule.setEnable(false);
//        this.CHK_DI.setEnable(false);
//        this.CHK_Motion.setEnable(false);
//        this.CHK_Manual.setEnable(false);
//        this.BTN_search.disabled = true;
    },
    
    setWidth : function(value){
        /* loading block */
        this.pvtLoadingBlock.style.width = value;
        this.pvtSyncBlock.style.width = value;

        /* timetrack area = value - (3(margin) - 25(button))*2 */
        var real = this.pvtTrackerWidth = value - (3+25) * 2;
        if(value>1050){
            this.pvtStartTimeLegend.style.display = "";
            this.pvtEventTypeLegend.style.display = "";
            YAHOO.util.Dom.removeClass(this.pvtTitleCenter, "small");
        } else {
            this.pvtStartTimeLegend.style.display = "none";
            this.pvtEventTypeLegend.style.display = "none";
            YAHOO.util.Dom.addClass(this.pvtTitleCenter, "small");
        }
        this.pvtTracker.setWidth(real);
        this.setCurrentTime(this.pvtCurrentTime);
    },
    
    setTimeSpan : function(value){
        var me = this;
        //this.pvtSearchCamera = this.pvtSelectedCamera;
        /* value: hour / day */
        if(this.pvtTimeSpanValue==value || (value!="hour" && value!="day")) return;
        /* set timespan value */
        this.pvtTimeSpanValue = value;
        /* remove old track */
        if(this.pvtTracker) this.pvtTracker.disrender();
        /* enable button */
        if(value=="hour"){
            this.BTN_1hour.setActivation(true);
            this.BTN_1day.setActivation(false);
            this.pvtTracker = this.pvtTrackerHourBase;
        } else {
            this.BTN_1hour.setActivation(false);
            this.BTN_1day.setActivation(true);
            this.pvtTracker = this.pvtTrackerDayBase;
        }
        /* render new track */
        this.pvtTracker.render(this.pvtMainTrack);
        /* timeout for track render */
        this.refreshTimespan();
    },
    
    getTimeSpan : function(){
        return this.pvtTimeSpanValue;
    },
    
    getSelectedCamera : function(){
        return this.pvtSelectedCamera;
    },
    
    setCurrentTime : function(value){
        if(!value){
            YAHOO.util.Dom.addClass(this.pvtPointer, "hide");
            this.pvtCurrentTime = null;
            return;
        } else if(value && this.pvtPointer.style.display=="none") {
            this.pvtPointer.style.display = "block";
        }
        this.pvtCurrentTime = value;
        /* draw objects */
        YAHOO.util.Dom.removeClass(this.pvtPointer, "hide");
        var starttimelong = this.pvtTracker.pvtTime.start.date.valueOf();
        var endtimelong = this.pvtTracker.pvtTime.end.date.valueOf();
        var range = endtimelong - starttimelong;
        var width = this.pvtTracker.totalWidth;

        var st = Math.floor( ( (value<starttimelong ? starttimelong : value) -starttimelong) / range * width );
        this.pvtPointer.style.left = st;
    },
    
    setCamera : function(obj, norefresh){
        if(this.pvtSelectedCamera===obj) return false;
        else {
            this.pvtSelectedCamera = obj;
            this.pvtCameraID.innerText = obj.NVR_CameraID;
            this.pvtCameraInfo.style.display = "block";
            /* after set camera, clear timeline */
            this.setCurrentTime(null);
            if(!norefresh) this.refreshSearch();
            return true;
        }
    },

    syncTime : function(obj){
        /* sync timetrack with channel and goto time */
        this.setCamera(obj.channel, true);
        //this.pvtSearchCamera = this.pvtSelectedCamera;
        this.pvtTracker.syncTime(obj);
        //this.setCurrentTime(this.pvtCurrentTime);
    },
    
    /*
        refresh resize=setWidth(): setWidth, redrawBanner, redrawBlock
        refresh search=refreshSearch(): setTime
        refresh timespan=refreshTimespan(): setWidth, redrawBanner, setTime
        refresh move=refreshTimespan()
    */
    refreshSearch : function(){
        if(this.pvtSelectedCamera == null){
           top.AP.showDialog({
                title : LANG("ID_CAMERASETUP_MSG_ERROR"),
                content : LANG("ID_NOCAMERA_SEARCH"),
                button : true,
                buttonText : LANG("ID_CONFIRM")
           });
        }
        if(!this.CHK_Schedule.getEnable() && !this.CHK_Motion.getEnable() && !this.CHK_DI.getEnable() && !this.CHK_Manual.getEnable()){
           top.AP.showDialog({
                title : LANG("ID_CAMERASETUP_MSG_ERROR"),
                content : LANG("ID_ALERT_PLS_SELECT_EVENT"),
                button : true,
                buttonText : LANG("ID_CONFIRM")
           });
           return;
        }
        //this.pvtSearchCamera = this.pvtSelectedCamera;
        this.setTime({
            day : this.pvtCalendarYearText.innerText,
            hour : this.pvtDropDownHour.getValue(),
            minute : this.pvtDropDownMinute.getValue()
        });
    },
    
    refreshTimespan : function(){
        if(this.pvtTrackerWidth) this.pvtTracker.setWidth(this.pvtTrackerWidth);
        this.setTime({
            day : this.pvtCalendarYearText.innerText,
            hour : this.pvtDropDownHour.getValue(),
            minute : this.pvtDropDownMinute.getValue()
        });
    },
    
    setTime : function(obj, noreload){
        var me = this;
        this.showLoadingBlock(true);
        setTimeout( function(){
            me.pvtTracker.setTime(obj, noreload);
            me.showLoadingBlock(false);
            setTimeout( function(){
                me.onDraw.fire();
            }, 1);
        }, 1 );
    },
    
    /* previous or next */    
    move : function(value){
        var me = this;
        //this.pvtSearchCamera = this.pvtSelectedCamera;
        /* get data */
        var day = this.pvtCalendarYearText.innerText;
        var hour = new Number(this.pvtDropDownHour.getValue());
        var minute = new Number(this.pvtDropDownMinute.getValue());
        var dateobj = new Date(day+" "+hour+":"+minute+":00");
        switch(this.pvtTimeSpanValue){
            case "hour":
                dateobj.setHours(hour+value);
                break;
            case "day":
                dateobj.setDate(dateobj.getDate()+value);
                break;
        }
        /* set back */
        this.pvtCalendarYearText.innerText = day = aui.lang.Date.format( dateobj, "%Y/%m/%d" );
        this.pvtDropDownHour.setValue(hour = dateobj.getHours());
        this.pvtDropDownMinute.setValue(minute = dateobj.getMinutes());
        /* set time */
//        this.setTime({
//            day : day,
//            hour : hour,
//            minute : minute
//        });
        this.refreshTimespan();
        setTimeout( function(){me.setCurrentTime(me.pvtCurrentTime)}, 1 );
    },
    
	pvtShowInfo : function(value, options){
	    if(!value){
	        try{ this._managedNode.removeChild(this.pvtInfoBlock); }catch(e){}
	    } else {
	        /* options: object, Model, ID, Name, IP, Channel, FPS, Resolution, MediaSource */
	        var region = YAHOO.util.Dom.getRegion(options.object);
	        /* set text */
            if(options.Model.substr(0,3) == 'RTP' || options.Model.substr(0,4) == 'HTTP' ){
                this.pvtInfoBlock.childNodes[3].style.display= 'none';
            }
            else{
                this.pvtInfoBlock.childNodes[3].style.display= 'block';
            }
	        this.pvtInfoBlock.pvtModel.innerText = options.Model;
	        this.pvtInfoBlock.pvtID.innerText = options.ID;
	        this.pvtInfoBlock.pvtName.innerText = options.Name;
	        this.pvtInfoBlock.pvtIP.innerText = options.IP;
	        this.pvtInfoBlock.pvtChannel.innerText = options.Channel;
	        this.pvtInfoBlock.pvtFPS.innerText = options.FPS;
	        this.pvtInfoBlock.pvtResolution.innerText = options.Resolution;
	        this.pvtInfoBlock.pvtMediaSource.innerText = options.MediaSource;
	        /* show */
	        this._managedNode.appendChild(this.pvtInfoBlock);
	        YAHOO.util.Dom.setXY(this.pvtInfoBlock, [region.right, region.top]);
        }
	},

    showLoadingBlock : function(value){
        if(value) this._managedNode.appendChild(this.pvtLoadingBlock);
        else if(this.pvtLoadingBlock.parentElement) this._managedNode.removeChild(this.pvtLoadingBlock);
    },
    
    showSyncBlock : function(value){
        if(value) this._managedNode.appendChild(this.pvtSyncBlock);
        else if(this.pvtSyncBlock.parentElement) this._managedNode.removeChild(this.pvtSyncBlock);
    },

    startSync : function(){
        this.showSyncBlock(true);
    },
    
    stopSync : function(){
        this.showSyncBlock(false);
    }
});


/* pointer for tracker */
aui.nvr2.ui.TimeTrack.pointer = function(name){
    var obj = document.createElement("div");
    obj.className = "pointer";
    if(name) obj.innerText = name;
    return obj;
}

/* TimespanBase, for HourBase and DayBase */
aui.nvr2.ui.TimeTrack.TimespanBase = function(parent){
    var me = this;
    this.parent = parent;
    this.pvtTime = {start:null, end:null};
    this.trackCollections = [];
    this.pvtPointers = [];
    /* main div */
    this._managedNode = document.createElement("div");
    this._managedNode.className = "timetrackbase";
    
    this._managedNode.onmousemove = function(){
        var identify = event.srcElement.identify;
        if(!me.pvtTime.start) return;
        var starttimelong = me.pvtTime.start.date.valueOf();
        var endtimelong = me.pvtTime.end.date.valueOf();
        //var camera = me.parent.pvtSearchCamera;
        var camera = me.parent.pvtSelectedCamera;
        var range = endtimelong - starttimelong;
        var width = me.totalWidth;
        var st = Math.floor( (event.x / width * range + starttimelong) / 1000) * 1000;
        if(!identify){
            //me.parent.pvtMainTrackInfo_Time.innerText = aui.lang.Date.format(st, "%Y/%m/%d %H:%M:%S");
            me.parent.pvtMainTrackInfo_Time.innerText = AP.utility.formatDate(st, "%Y/%m/%d %H:%M:%S");
            me.parent.pvtMainTrackInfo_File.innerText = "";
            me.parent.pvtScrollBase.style.visibility = "hidden";
            me.parent.pvtSelectFile = "";
            return;
        }

        var camera = camera.Recordings;
        var pos = camera.getSiblingIndex({STARTTIME: st});
        var file;
        if(pos.current!=null) file = camera._array[pos.current];
        else if(pos.previous!=null && camera._array[pos.previous].ENDTIME>st) file = camera._array[pos.previous];
        else if(pos.next!=null){
            file = camera._array[pos.next];
            var st = file.STARTTIME;
        }
        me.parent.pvtSelectTime = st;
        //me.parent.pvtMainTrackInfo_Time.innerText = aui.lang.Date.format( st, "%Y/%m/%d %H:%M:%S");
        me.parent.pvtMainTrackInfo_Time.innerText = AP.utility.formatDate( st, "%Y/%m/%d %H:%M:%S");
        if(!file){
            me.parent.pvtMainTrackInfo_File.innerText = "";
            me.parent.pvtScrollBase.style.visibility = "hidden";
            return;
        }
        me.parent.pvtMainTrackInfo_File.innerText = me.parent.pvtSelectFile = file.FILELOCATION;
        /* draw scroll */
        me.parent.pvtScrollBase.style.visibility = "visible";
        var now = Math.round( (st-file.STARTTIME) / 1000 );
        var total = Math.round( (file.ENDTIME-file.STARTTIME) / 1000 ) || 1;
        me.parent.pvtScrollBall.style.left = Math.round( now / total * 33 );
        var sec = now % 60;
        me.parent.pvtTimeNow.innerText = [ (now-sec)/60, aui.text.String.padLeft(sec, 2, "0") ].join(":");
        sec = total % 60;
        me.parent.pvtTimeMax.innerText = [ (total-sec)/60, aui.text.String.padLeft(sec, 2, "0") ].join(":");
    }
    
    this._managedNode.onmousedown = function(){
        var file = me.parent.pvtSelectFile;
        if(!file) return;
        me.parent.onSelect.fire({
            channel: me.parent.pvtSelectedCamera,
            goto: me.parent.pvtSelectTime,
            file: file
        });
    }
    
    /* track object model */
    this.scheduleModel = document.createElement("div");
    this.scheduleModel.className = "scheduleModel";
    this.scheduleModel.identify = "track";

	/* schedule model addition */
		tmp2 = document.createElement("div");
		tmp2.style.top = 0;
		tmp2.style.width = 5;
		tmp2.style.height = 19;
		tmp2.style.left = -5;
		tmp2.style.position = 'absolute';
		tmp2.style.backgroundColor = '#8CAACE';
		tmp2.style.zIndex = 1000;
	
		tmp1 = document.createElement("div");
		tmp1.style.position = "relative";
		tmp1.appendChild(tmp2);
		this.scheduleModel.appendChild(tmp1);
	/* schedule model addition END */
	
    this.diModel = document.createElement("div");
    this.diModel.className = "diModel";
    this.diModel.identify = "track";

    this.motionModel = document.createElement("div");
    this.motionModel.className = "motionModel";
    this.motionModel.identify = "track";

    this.manualModel = document.createElement("div");
    this.manualModel.className = "manualModel";
    this.manualModel.identify = "track";
    /*
    this.PIRModel = document.createElement("div");
    this.PIRModel.className = "motionModel";
    this.PIRModel.identify = "track";
    */
}
aui.nvr2.ui.TimeTrack.TimespanBase.prototype = {
    pvtTime : null,
    pvtRecord : null,
    totalWidth : null,      // totalWidth of current timespan
    
    pvtTimeOffset : null,   // How many seconds could be seen in timespan
    
    pvtEventType : null,    // Keep event type settings of last search
    
    scheduleModel : null,
    diModel : null,
    motionModel : null,
    manualModel : null,
    //PIRModel : null,
    
    trackCollections : null,

    /* refresh track data */
    refresh : function(noreload){
        var me = this;
        //var camera = this.parent.pvtSearchCamera;
        var camera = this.parent.pvtSelectedCamera;
        //var starttime = this.pvtTime.start.valueOf;
        //var endtime = this.pvtTime.end.valueOf;
        var starttime = this.pvtTime.start.date.valueOf();
        var endtime = this.pvtTime.end.date.valueOf();
        if(!starttime || !endtime || !camera || !this.totalWidth) return;
        var startUTCString = AP.utility.formatDate(starttime, "%Y-%m-%d %H:%M:%S");
        var endUTCString = AP.utility.formatDate(endtime, "%Y-%m-%d %H:%M:%S");
        var recordings = camera.Recordings;

        if(!noreload || recordings.reQueue){
            /* 1) remove records */
            recordings._array = [];

            /* event type */
            var eventtype = [];
            if(this.parent.CHK_Schedule.getEnable()) eventtype.push("Schedule");
            if(this.parent.CHK_Manual.getEnable()) eventtype.push("Manual");
            if(this.parent.CHK_DI.getEnable()) eventtype.push("Alarm");
            if(this.parent.CHK_Motion.getEnable()) {
                eventtype.push("Motion");
                eventtype.push("PIR");
            }    
            //if(this.parent.CHK_PIR.getEnable()) eventtype.push("PIR");
            this.pvtEventType = eventtype;

            /* 2) keep start / end time */
            recordings.pvtStartTime = starttime;
            recordings.pvtEndTime = endtime;

            /* 3) insert recordings */
            var obj = AP.database.getRecordsForTimeTrack(camera, {
                STARTTIME : startUTCString,
                ENDTIME : endUTCString,
                EVENT_TYPE : eventtype
            });
            recordings.insertXMLData(obj);

            /* 4) decide Standard_Bias and Daylight_Bias */
            if(recordings._array && recordings._array.length>0){
                if(recordings._array[0].STANDARD_BIAS) AP.standardBias = parseInt(recordings._array[0].STANDARD_BIAS || 0, 10)*60*1000;
                if(recordings._array[0].DAYLIGHT_BIAS) AP.daylightBias = parseInt(recordings._array[0].DAYLIGHT_BIAS || 0, 10)*60*1000;
                this._updateTimeValue();
            }

            /* 5) update reQueue: true while during now */
            var now = this.parent.pvtSelectedCamera.NVRReference.getServerTime();
            recordings.reQueue = (now<this.pvtTime.end.date.valueOf() && now>this.pvtTime.start.date.valueOf()) ? true : false;

            recordings = recordings._array;

            
//        } else if(recordings.reQueue) {
//            /* 1) refresh startUTCString */
//            if(recordings._array.length>0) startUTCString = aui.lang.Date.format(recordings._array[recordings._array.length-1].ENDTIME, "%Y-%m-%d %H:%M:%S", true);
//            window.status = startUTCString+":"+endUTCString;
//            //window.status += ":"+aui.lang.Date.format(recordings._array[recordings._array.length-1].STARTTIME, "%Y-%m-%d %H:%M:%S", true) + ":" + aui.lang.Date.format(recordings._array[recordings._array.length-1].ENDTIME, "%Y-%m-%d %H:%M:%S", true);
//            /* 2) insert recordings */
//            var obj = AP.database.getRecordsForTimeTrack(camera, {
//                STARTTIME : startUTCString,
//                ENDTIME : endUTCString,
//                EVENT_TYPE : this.pvtEventType
//            });
//            recordings.appendXMLData(obj);

//            /* 3) update reQueue: true while during now */
//            var now = new Date().valueOf();
//            recordings.reQueue = (now<endtime.valueOf() && now>starttime.valueOf()) ? true : false;

//            recordings = recordings._array;
        } else {
            recordings = recordings._array;
        }
        /* 4) redraw */
        this.redraw(recordings);
    },
    
    dropBlocks : function(){
        while(this.trackCollections.length>0){
            var obj2 = this.trackCollections.pop();
            if(obj2.parentElement) this._managedNode.removeChild(obj2);
        }
    },
    
    redraw : function(ary){
        var me = this;
        if(!ary) ary = this.pvtRecord;
        if(!ary) return;
        this.pvtRecord = ary;
        /* remove previous objects */
        this.dropBlocks();
        /* draw objects */
        var starttimelong = this.pvtTime.start.date.valueOf();
        var endtimelong = this.pvtTime.end.date.valueOf();

        var range = endtimelong - starttimelong;
        var width = this.totalWidth;
        var lastst, lasted, nowobj, lastevt;
        
        function posObject(){
            nowobj.style.width = lasted-lastst+1;
            nowobj.style.left = lastst;
            me._managedNode.appendChild(nowobj);
        }
        function detectEvtType(obj){
            if(obj.REC_TYPE=="WithStreaming" && obj.EVENT_TYPE=="Alarm") return "di";
            else if(obj.REC_TYPE=="WithStreaming" && (obj.EVENT_TYPE=="Motion" || obj.EVENT_TYPE=="PIR")) return "motion";
            else if(obj.REC_TYPE=="Manual") return "manual";
            else return "schedule";
        }
        for(var i in ary){ 
            var tmp = ary[i];
            if(tmp.FILELOCATION=="") continue;
            var st = (tmp.STARTTIME<starttimelong ? starttimelong : tmp.STARTTIME) -starttimelong;
            var ed = (tmp.ENDTIME>endtimelong ? endtimelong : tmp.ENDTIME) -starttimelong;
            if(ed<=st) continue;
            
            st = Math.floor( st / range * width );
            ed = Math.floor( ed / range * width );
            var evt = detectEvtType(tmp);
            
            if(lasted==null || st-lasted>1 || evt!=lastevt){
                if(lasted!=null) posObject();
                nowobj = this[evt+"Model"].cloneNode(true);
                this.trackCollections.push(nowobj);
                lastst = st;
                lasted = ed;
                lastevt = evt;
            } else {
                lasted = ed;
            }
        }
        if(nowobj) posObject();
    },
    
    syncTime : function(obj){
        /* obj: channel, goto */
        var recordings = obj.channel.Recordings;
        var time = this.pvtTime.start;
        /* 1) check time with current showing timespan */
        var inrange = false;

        this._updateTimeValue();
        if(obj.goto<=this.pvtTime.end.date.valueOf() && obj.goto>=this.pvtTime.start.date.valueOf()) inrange = true;
        /* 2) decide seeable time */
        if(!inrange){
            if(time.date.valueOf()<=obj.goto && time.date.valueOf()>=obj.goto){
                /* seeable */
            } else {
                /* set time to seeable */
                var synctime = new Date(obj.goto);
                var scvalue = synctime.valueOf();
                switch(this.proto){
                    case aui.nvr2.ui.TimeTrack.HourBase:
                        /* keep minute */
                        var minute = parseInt(AP.utility.formatDate(time.date.valueOf(), "%M"), 10);
                        /* alter */
                        var num = obj.goto + (minute - parseInt(AP.utility.formatDate(obj.goto, "%M"), 10))*60*1000;
                        if(num>obj.goto) num -= 60*60*1000;
                        /* get day & hour */
                        var day = AP.utility.formatDate(num, "%Y/%m/%d");
                        var hour = AP.utility.formatDate(num, "%H");
                        
//                        synctime.setMinutes(time.date.getMinutes());
//                        if(synctime.valueOf()>scvalue) synctime.setHours(synctime.getHours()-1);
                        
                        break;
                    case aui.nvr2.ui.TimeTrack.DayBase:
                        /* keep hour and minute */
                        var minute = parseInt(AP.utility.formatDate(time.date.valueOf(), "%M"), 10);
                        var hour = parseInt(AP.utility.formatDate(time.date.valueOf(), "%H"), 10);
                        /* alter */
                        var num = obj.goto + (hour - parseInt(AP.utility.formatDate(obj.goto, "%H"), 10))*60*60*1000 + (minute - parseInt(AP.utility.formatDate(obj.goto, "%M"), 10))*60*1000;
                        if(num>obj.goto) num -= 24*60*60*1000;
                        /* get day */
                        var day = AP.utility.formatDate(num, "%Y/%m/%d");
                        
//                        synctime.setHours(time.date.getHours(), time.date.getMinutes());
//                        if(synctime.valueOf()>scvalue) synctime.setDate(synctime.getDate()-1);
                        break;
                }
            }
//            time = {
//                day : aui.lang.Date.format(synctime, "%Y/%m/%d"),
//                hour : synctime.getHours(),
//                minute : synctime.getMinutes()
//            }
            time = {
                day : day,
                hour : parseInt(hour,10),
                minute : parseInt(minute,10)
            }
        }
        /* 3) check time with records */
        inrange = false;
        if(obj.goto>=recordings.pvtStartTime && obj.goto+this.pvtTimeOffset<=recordings.pvtEndTime) inrange = true;
        /* 4) return time and range */
        this.parent.setTime(time, inrange);
        /* 5) sync date legend */
        this.parent.pvtCalendarYearText.innerText = time.day;
        this.parent.pvtDropDownHour.setValue(time.hour);
        this.parent.pvtDropDownMinute.setValue(time.minute);
    },
    
    _updateTimeValue : function(){
        if(!this.parent.pvtSelectedCamera){
            this.pvtTime.start.valueOf = null;
            this.pvtTime.end.valueOf = null;
        } else {
            var standard = AP.standardBias;
            var daylight = AP.daylightBias;
            this.pvtTime.start.valueOf = this.pvtTime.start.date.valueOf() - daylight - standard;
            this.pvtTime.end.valueOf = this.pvtTime.end.date.valueOf() - daylight - standard;
        }
    }
}

/* HourBase and DayBase */
aui.nvr2.ui.TimeTrack.HourBase = function(parent){
    this.proto.superclass.constructor.call(this, parent);
    /* create pointers */
    for(var i=0; i<12; i++){
        var obj = new aui.nvr2.ui.TimeTrack.pointer();
        this.pvtPointers.push( obj );
        this._managedNode.appendChild(obj);
    }
}
aui.lang.Class.extend(aui.nvr2.ui.TimeTrack.HourBase, aui.nvr2.ui.TimeTrack.TimespanBase, {
    proto : aui.nvr2.ui.TimeTrack.HourBase,
    
    pvtTimeOffset : 60,

    render : function(appendToNode){
        appendToNode.appendChild(this._managedNode);
    },
    
    disrender : function(){
        this._managedNode.parentNode.removeChild(this._managedNode);
    },
    
    setWidth : function(value){
        value = value || this.totalWidth;
        this._managedNode.style.width = value+"px";
        /* reposition pointers */
        var ref = Math.floor(value / 12);
        for(var i in this.pvtPointers){
            var obj = this.pvtPointers[i];
            obj.style.left = ref*i;
        }
        this.totalWidth = ref*12;
        this.redraw();
    },
    
    setTime : function(obj, noreload){
        noreload = noreload || false;
        /* obj: day, hour, minute */
        //obj.date = new Date(obj.day+" "+obj.hour+":"+obj.minute+":00");
        var tmp = obj.day.split("/");
        obj.date = new Date(Date.UTC(tmp[0], parseInt(tmp[1],10)-1, tmp[2], obj.hour, obj.minute, 0));
        this.pvtTime.start = obj;
        /* change pointers text */
        var hour = obj.hour = new Number(obj.hour);
        var minute = obj.minute = new Number(obj.minute);
        this.redrawBlocks();
        /* count end date */
        this.pvtTime.end = {};
        var dateobj = this.pvtTime.end.date = new Date(Date.UTC(tmp[0], parseInt(tmp[1],10)-1, tmp[2], obj.hour, obj.minute, 0));
        dateobj.setHours( dateobj.getHours()+1 );
        this.pvtTime.end.day = AP.utility.formatDate(dateobj, "%Y/%m/%d");
        this.pvtTime.end.hour = AP.utility.formatDate(dateobj, "%H");
        this.pvtTime.end.minute = AP.utility.formatDate(dateobj, "%M");
        this._updateTimeValue();
        
        this.refresh(noreload);
    },
    
    redrawBlocks : function(){
        var hour = this.pvtTime.start.hour;
        var minute = this.pvtTime.start.minute;
        if(!hour || !minute) return;
        for(var i in this.pvtPointers){
            var tmp = this.pvtPointers[i];
            tmp.innerText = aui.text.String.padLeft(hour, 2, "0")+":"+aui.text.String.padLeft(minute, 2, "0");
            minute += 5;
            hour += Math.floor(minute / 60);
            minute %= 60;
            hour %= 24;
        }
    }
});

aui.nvr2.ui.TimeTrack.DayBase = function(parent){
    this.proto.superclass.constructor.call(this, parent);
    /* create pointers */
    for(var i=0; i<24; i++){
        var obj = new aui.nvr2.ui.TimeTrack.pointer();
        this.pvtPointers.push( obj );
        this._managedNode.appendChild(obj);
    }
}
aui.lang.Class.extend(aui.nvr2.ui.TimeTrack.DayBase, aui.nvr2.ui.TimeTrack.TimespanBase, {
    proto : aui.nvr2.ui.TimeTrack.DayBase,

    pvtTimeOffset : 60*24,

    render : function(appendToNode){
        appendToNode.appendChild(this._managedNode);
    },
    
    disrender : function(){
        this._managedNode.parentNode.removeChild(this._managedNode);
    },
    
    setWidth : function(value){
        value = value || this.totalWidth;
        this._managedNode.style.width = value+"px";
        /* font size */
        if(value<1000){
            YAHOO.util.Dom.addClass(this._managedNode, "small");
        } else {
            YAHOO.util.Dom.removeClass(this._managedNode, "small");
        }
        /* reposition pointers */
        var ref = Math.floor(value / 24);
        for(var i in this.pvtPointers){
            var obj = this.pvtPointers[i];
            obj.style.left = ref*i;
        }
        this.totalWidth = ref*24;
        this.redraw();
    },
    
    setTime : function(obj, noreload){
        noreload = noreload || false;
        /* obj: day, hour, minute */
        var tmp = obj.day.split("/");
        obj.date = new Date(Date.UTC(tmp[0], parseInt(tmp[1],10)-1, tmp[2], obj.hour, obj.minute, 0));
        this.pvtTime.start = obj;
        /* change pointers text */
        var hour = obj.hour = new Number(obj.hour);
        var minute = obj.minute = new Number(obj.minute);
        this.redrawBlocks();
        /* count end date */
        this.pvtTime.end = {};
        var dateobj = this.pvtTime.end.date = new Date(Date.UTC(tmp[0], parseInt(tmp[1],10)-1, tmp[2], obj.hour, obj.minute, 0));
        dateobj.setDate( dateobj.getDate()+1 );
        this.pvtTime.end.day = AP.utility.formatDate(dateobj, "%Y/%m/%d");
        this.pvtTime.end.hour = AP.utility.formatDate(dateobj, "%H");
        this.pvtTime.end.minute = AP.utility.formatDate(dateobj, "%M");

        this.refresh(noreload);
    },
    
    redrawBlocks : function(){
        var hour = this.pvtTime.start.hour;
        var minute = this.pvtTime.start.minute;
        if(!hour || !minute) return;
        var minutetext = aui.text.String.padLeft(minute, 2, "0");
        /* change pointers text */
        for(var i in this.pvtPointers){
            var tmp = this.pvtPointers[i];
            tmp.innerText = aui.text.String.padLeft(hour, 2, "0")+":"+minutetext;
            hour += 1;
            hour %= 24;
        }
    }
});