var svgns = "http://www.w3.org/2000/svg";
$(function () {
    // "custom" is the namespace"gantt" is the widget name
    $.widget("custom.gantt", {
        // default options
        options: {
            offsetLeft: 100,    //static
            offsetRight: 0,    //static
            offsetVertical:0,  //static
            width: 850,     // once, from html definition
            height: 350,    // once, from html definition
            aceCoordLength : 700,   // once, computed in constructor
            title: "Gantt",     // once, from html definition in constructor
            id: "Gantt1",   // once, from html definition in constructor              

            rowHeight: 50,
            rowsNum: 0,

            startTs: null,  //ok - once, from html def
            endTs: null,    //ok - once, from html def
            viewStartTs: null,  // default startTs, change when move and zoom events
            viewEndTs: null,    //default startTs, change when move and zoom events

            //setting from HTML definition
            showGrid: false,    
            enableDialog: false,            
            enableOption: false,
            enableDragDrop: false,  
            enableEdit: false,
            enableGridSnap: false,
            showMouseCursor: false,
            showStripeTitle: false,

            /*Callbacks*/
            onDataObtain: null,
            onDataFailed: null           
        },
        GanttData: {},
        GanttRowsKeys: [],

        drawArea: SVGElement,
        titleArea: HTMLElement,
        toolBar: HTMLElement,
        timeLine: HTMLElement,

        ganttLoadDataUrl: null,
        ganttSaveDataUrl: null,
        stripeDetailUrl: null,

        // the constructor
        _create: function () {
            with (this.options)
            {
                /*Fill options*/
                width = Number(this.element.attr("width"));
                height = Number(this.element.attr("height"));
                aceCoordLength = width - offsetLeft - offsetRight;
                title = this.element.attr("GanttTitle");
                id = this.element.id;   
                
                startTs = Number(this.element.attr("startTs"));
                endTs = Number(this.element.attr("endTs"));
                viewStartTs = Number(this.element.attr("viewStartTs"));
                viewEndTs = Number(this.element.attr("viewEndTs"));

                showGrid = toBoolean(this.element.attr("showGrid"));
                enableDialog = toBoolean(this.element.attr("enableDialog"));
                enableOption = toBoolean(this.element.attr("enableOption"));
                enableDragDrop = toBoolean(this.element.attr("enableDragDrop"));
                enableEdit = toBoolean(this.element.attr("enableEdit"));
                showMouseCursor = toBoolean(this.element.attr("showMouseCursor"));
                showStripeTitle = toBoolean(this.element.attr("showStripeTitle"));
                enableGridSnap = toBoolean(this.element.attr("enableGridSnap"));
            }

            this.ganttLoadDataUrl = this.element.attr("ganttLoadDataUrl");
            this.ganttSaveDataUrl = this.element.attr("ganttSaveDataUrl");
            this.stripeDetailUrl = this.element.attr("stripeDetailUrl");

            /*Container SVG */
            this.element.css("height", this.options.height).css("width", this.options.width+50).disableSelection();
            /*Title*/
            this.titleArea = $("<div>", { "class": "ganttTitle" }).appendTo(this.element);
            this.titleArea.html(this.options.title);
            /*Toolbar*/
            this.toolBar = createToolBar($(this)).appendTo(this.element);
            /*Timeline*/
            this.timeLine = $("<div>", { "class": "timeLine", "id": "ganttTimeLine", "width": this.options.aceCoordLength })
                .css("margin-left", this.options.offsetLeft)
                .appendTo(this.element);

            $("<div>", { "class": "topTimeLine", "id": "topTimeLine", "width": this.options.aceCoordLength }).appendTo( this.timeLine);
            $("<div>", { "class": "botTimeLine", "id": "botTimeLine", "width": this.options.aceCoordLength }).appendTo( this.timeLine);

            /*Gantt area*/
            this.drawArea = $("<svg xmlns='http://www.w3.org/2000/svg'>",{
                "class": "gantt-draw-area",
                "id": this.options.id
            }).attr("class", "gantt-draw-area")
              .attr("height", this.options.height-this.options.offsetVertical)
              .attr("width", this.options.width)
              .appendTo(this.element);                
          
            /*Options dialog*/
            if (this.options.enableOption)
            {
                var optionsDialog = createOptionsDialog();

                optionsDialog.appendTo(this.element);
                
                $("#optionsDialog input").change(function (event) {
                    var options = $(this).attr("name");
                    var value = $(this).is(":checked");
                    gantt.setOption(options, value);
                });
                $("#optionsDialog").dialog({
                    autoOpen: false,
                    width: 300,
                    height: 300
                });
            }

            if (this.options.enableDialog)
            {
                var detailDialog = $('<div>', {
                    "id": "detailDialog",
                    "title": "Detail",
                    "detailUrl":this.stripeDetailUrl
                }).append("<iframe src='' width='600' height='300' id='detailUrl'>")

                detailDialog.appendTo(this.element);

                $("#detailDialog").dialog({
                    autoOpen: false,
                    width: 400,
                    height: 400
                });
            }

            /*Bind events*/
            var gantt = this;
            this.toolBar.find("#zoomIn").bind('click', function (event){gantt.zoomIn()});
            this.toolBar.find("#zoomOut").bind('click', function (event){gantt.zoomOut()});

            this.toolBar.find("#shiftLeft").bind('click', function (event){gantt.timeShiftLeft()});
            this.toolBar.find("#shiftRight").bind('click', function (event){gantt.timeShiftRight()});

            this._on(this.toolBar.find("#addItem").eq(0), { click: "addStripe" });

            if (this.options.enableOption)
            {
                this._on(this.toolBar.find("#openSetting").eq(0), { click: "openOptionsDialog" });
            }
            else
            {
                this.toolBar.find("#openSetting").addClass("disableBarCell");
            }

            this._on(this.toolBar.find("#save").eq(0), { click: "saveGanttfunData" });
            
            this.timeLine.bind('mousedown', function (e) {
                var startX = 0;

                console.log("start");
                $(this).on('mousemove', function (e) {
                    console.log("move");
                });

                $(this).on('mouseup', function (e) {
                    console.log("enddrag");
                    $(this).off('mouseup mousemove');
                });          
            });            

                this.element.find(".gantt-draw-area").bind('mousewheel', function (event) {                
                if (event.originalEvent.wheelDelta == 120)
                    gantt.zoomIn();
                else if(event.originalEvent.wheelDelta == -120)
                    gantt.zoomOut();
                event.preventDefault();
            });
            this.element.find(".gantt-draw-area").bind('mouseenter', function () { $("#cursorTitle").removeClass("hidden") });
            this.element.find(".gantt-draw-area").bind('mouseleave', function () { $("#cursorTitle").addClass("hidden") });

            this.loadGanttData();
            //this._refresh();
        },
        // called when created, and later when changing options
        _refresh: function () {
            //kazdy element se vykresli znovu, takze je mozne provest nejakou optimalizaci 
            //clean
            this.element.find(".stripe").remove();
            this.element.find(".borderLine").remove();
            this.element.find(".rowTitle").remove();
            this.element.find(".timeTitle").remove();
            this.element.find(".stripeTitle").remove();
            this.element.find(".timeBar").remove();
            this.element.find(".gridLine").remove();
            this.GanttRowsKeys = [];

            var gantt = this;
            var startDate = new Date(this.options.viewStartTs );
            var endDate = new Date(this.options.viewEndTs);

            startDate.setHours(startDate.getHours()-1);
            endDate.setHours(endDate.getHours()-1);

            $("#topTimeLine").html(startDate.toLocaleString() + " - " + endDate.toLocaleString());

            //draw gantt
            var i = 0;
            for (var item in this.GanttData) {
                //generate lines
                var row = this.GanttData[item];
                this.GanttRowsKeys[i] = item;
                var text = createText(5, 30 + (this.options.rowHeight * i), row.rowTitle, "rowTitle");
                text.appendTo(this.drawArea);

                var lineSeparator = createLine(this.options.offsetLeft, this.options.offsetVertical + (this.options.rowHeight * (i+1)), this.options.width - 1, this.options.offsetVertical + (this.options.rowHeight * (i+1)), "borderLine");
                lineSeparator.appendTo(this.drawArea);

                var stripes = row.stripes;
                for (var rowItem in stripes) {
                    var stripe = stripes[rowItem];

                    if(!stripe.visible)
                        { continue;}

                    var sx = getXCoord(this.options, stripe.startTs);
                    var ex = getXCoord(this.options, stripe.endTs); //-(1000*60*60)

                    if (sx == -1 && ex > 0) { sx = this.options.offsetLeft; }                            
                    if (ex == -999 && sx > 0) { ex = this.options.aceCoordLength + this.options.offsetLeft; }
                    if (ex == -999 && sx == -1) { sx = this.options.offsetLeft; ex = this.options.aceCoordLength + this.options.offsetLeft; }

                    var stripelength = ex - sx;

                    if (stripelength > 0) {
                        var ds = createRectangle(sx, 10 + (this.options.rowHeight * i), "stripe " + stripe.color, stripelength, stripe.stripeId, stripe.stripeTitle);
                        ds.attr({ "rowKey": stripe.rowId });
                        //ds.bind("click", this.getStripeData);
                        if (gantt.options.showStripeTitle)
                        {
                            var text = createText(sx + (stripelength / 2), 30 + (this.options.rowHeight * i), stripe.stripeTitle, "stripeTitle");
                            text.attr("id", "strTtl" + stripe.stripeId);
                            text.appendTo(this.drawArea);
                        }
                        ds.appendTo(this.drawArea);
                    }
                }
                i++;
                this.options.rowsNum = i;
            }
            this.drawArea.attr("height", i * this.options.rowHeight + 1);

            /*Gant border*/
            createDrawingBorder(this.drawArea, this.options);

            //TEST
            var unit = getAceUnits(this.options, this.timeLine, this.drawArea);
            //console.log(unit);

            if (this.options.showMouseCursor)
            {
                if (this.drawArea.find(".cursorLine").length == 0)
                {
                    var ey = this.options.rowsNum * this.options.rowHeight + this.options.offsetVertical + 1;
                    var cursor = createLine(this.options.offsetLeft + 1, this.options.offsetVertical, this.options.offsetLeft + 1, ey, "cursorLine");
                    cursor.attr({ "id": "cursorLine" });
                    this.drawArea.prepend(cursor);

                    var cursorTitle = $("<div>", { "class": "cursorTitle", "id": "cursorTitle" }).append("<span id='cursorTitleValue'>Datum</span>").addClass("hidden").appendTo(this.element);
                }
                this.element.find(".gantt-draw-area").eq(0).bind("mousemove", function (event) { gantt.mousemove(event) });
            }
            else
            {
                this.element.find(".gantt-draw-area").eq(0).unbind("mousemove");
                $("#cursorTitle").remove();
                $(".cursorLine").remove();
            }                

            //DragAndDrop();            
            if (this.options.enableDragDrop)
            {
                $(".stripe").draggable({
                    startX: null,
                    starty: null,
                    grid: [1, this.options.rowHeight],
                    start: function (event, ui) {
                        startX = Number($(this).attr("x"));
                        startY = Number($(this).attr("y"));
                        $(this).parent().prepend($(this));
                    },
                    drag: function (event, ui) {

                        //PRESUN || zmena velikosti pri stiknuti ctrl
                        var position = ui.position;
                        var orgPosition = ui.originalPosition
                        var $rect = ui.helper;
                        var width = Number($rect.attr("width"));
                        var collision = false;
                        var draggedId = $rect.attr("stripeId");
                        var newX = startX + (position.left - orgPosition.left);
                        var newY = startY + (position.top - orgPosition.top);                       

                        if (gantt.options.enableGridSnap)
                        {
                            $(".gridLine").each(function () {
                                var gridLineX = Number($(this).attr("x1"));
                                var currMouseX = event.offsetX;

                                if (currMouseX >= (gridLineX - 5) && currMouseX <= (gridLineX + 5)) {
                                    newX = gridLineX;
                                }
                            });
                        }                        

                        //Kontrola, jestli se elementy neprekryvaji
                        $(".stripe[y='" + newY + "']").each(function () {
                            if (draggedId != $(this).attr("stripeId"))
                            {
                                var tsX = Number($(this).attr("x"));
                                var teX = Number($(this).attr("x")) + Number($(this).attr("width"));
                                var dsX = newX;
                                var deX = dsX + width;                                

                                if( (dsX >= tsX && dsX <= teX) || (deX >= tsX && deX <= teX) || (dsX <= tsX && deX >= teX) )
                                {
                                    collision = true;
                                    return false;
                                }
                            }
                        });                                                                                     

                        if (!collision) {
                            var elmWidth = Number($rect.attr("width"));
                            if (newY < gantt.options.offsetVertical) { newY = gantt.options.offsetVertical + 10; }
                            if (newY > i * gantt.options.rowHeight + gantt.options.offsetVertical) { newY = (i - 1) * gantt.options.rowHeight + 10; }

                            if (newX + elmWidth > gantt.options.width) { newX = gantt.options.width - elmWidth; }
                            if (newX < gantt.options.offsetLeft) { newX = gantt.options.offsetLeft; }


                            if (gantt.options.showStripeTitle) {
                                var $stripeTitle = $("#strTtl" + $rect.attr("stripeId"));                                
                                moveText($stripeTitle, newX + Number($rect.attr("width")) / 2, newY + 20);
                                $stripeTitle.parent().append($(this));
                            }
                            moveStripe($rect, newX, newY);
                            $rect.appendTo(gantt.drawArea);
                        }                     
                    },
                    stop: function (event, ui) {
                        
                        //$(".gridLine").off("mousemove");
                        var $rect = ui.helper;                        
                        var $stripeData = gantt.GanttData[$rect.attr("rowKey")].stripes[$rect.attr("stripeId")];                        
                        var row = Math.floor(((Number($rect.attr("y")) - gantt.options.offsetVertical) / gantt.options.rowHeight), 0);                        
                        var dataKey = gantt.GanttRowsKeys[row];

                        //set new stripe row ID
                        $stripeData.rowID = gantt.GanttData[dataKey].rowId;
                        $stripeData.startTs = getDateFromCoord(gantt.options, Number($rect.attr("x")));
                        $stripeData.endTs = getDateFromCoord(gantt.options, Number($rect.attr("x")) + Number($rect.attr("width")));
                        
                        gantt.saveGanttfunData($stripeData);
                    }
                }); //End drag and drop       
            } // drag&drop enabled end    
            /*Dialog*/
            if (this.options.enableDialog)
            {
                $(".stripe").bind("click", this.stripeDetail);
            }
            // trigger a callback/event
            //this._trigger("change");
        },
        /*Custom functions*/
        stripeDetail: function (event /*stripe data*/) {

            var stripeId = $(this).attr("stripeId");
            var url = $("#detailDialog").attr("detailUrl");
            $("#detailUrl").attr("src", url + "?id=" + stripeId);
            $("#detailDialog").dialog("open");
            //refresh v pripade nutnosti
        },
        addStripe: function (event) {
            var url = $("#detailDialog").attr("detailUrl");
            $("#detailUrl").attr("src", url + "?id=-1");
            $("#detailDialog").dialog("open");
        },
        //inicializace okna nastavení při otevření
        openOptionsDialog: function (event) {
            if (this.options.enableOption)
            {
                if (this.options.showGrid) $("#showGridChckbx").attr("checked",true); else $("#showGridChckbx").removeAttr("checked");
                if (this.options.showMouseCursor) $("#showMouseCursorChckbx").attr("checked","true"); else $("#showMouseCursorChckbx").removeAttr("checked");
                if (this.options.showStripeTitle) $("#showStripeTitleChckbx").attr("checked", "true"); else $("#showStripeTitleChckbx").removeAttr("checked");
                if (this.options.enableGridSnap) $("#enableGridSnap").attr("checked", "true"); else $("#enableGridSnap").removeAttr("checked");
                
                $("#optionsDialog").dialog("open");
            }             
        },
        //provedení změny v nastavení
        setOption: function (key, value) {
            $("#optionsDialog").dialog("close");
            this.options[key] = value;
            this._refresh();
            //doimplementovat
        },
        //posun casove osy vlevo
        timeShiftLeft: function () {
            if (this.options.viewEndTs > this.options.startTs)
            {
                var diff = ((this.options.viewEndTs - this.options.viewStartTs) * 0.1);
                this.options.viewStartTs -= (diff / 2);
                this.options.viewEndTs -= (diff / 2);
                this._refresh();
            }
        },
        //posun casove osy v pravo
        timeShiftRight: function () {
            if (this.options.viewStartTs < this.options.endTs)
            {
                var diff = ((this.options.viewEndTs - this.options.viewStartTs) * 0.1);
                this.options.viewStartTs += (diff / 2);
                this.options.viewEndTs += (diff / 2);
                this._refresh();
            }
        },
        //priblizeni
        zoomIn: function () {
            var diff = ((this.options.viewEndTs - this.options.viewStartTs) * 0.1);
            if(diff > 1000)
            {
                this.options.viewStartTs += (diff / 2);
                this.options.viewEndTs -= (diff / 2);
            }
            this._refresh();
        },
        //oddaleni
        zoomOut: function () {
            var diff = ((this.options.viewEndTs - this.options.viewStartTs) * 0.1);   
            this.options.viewStartTs -= (diff / 2);
            this.options.viewEndTs += (diff / 2);
            this._refresh();
        },
        //pohyb cursoru
        mousemove: function (event) {
            /*Udelat kotrolu rozmezi kam muzu posouvat*/
            //var newX = event.clientX - event.currentTarget.offsetLeft;
            var newX = event.offsetX;

            var newY = event.offsetY;

            if (newX > this.options.width)
                newX = this.options.width;

            if (newX < this.options.offsetLeft)
                newX = this.options.offsetLeft;

            if (newY < this.options.offsetVertical)
                newY = this.options.offsetVertical;

            if (newY > this.options.rowsNum * this.options.rowHeight + this.options.offsetVertical)
                newY = this.options.rowsNum * this.options.rowHeight + this.options.offsetVertical;

            
            //debugger;
            $("#cursorLine").attr({ 'x1': newX, 'x2': newX });
            $("#cursorTitle").css({ top: event.clientY +10, left: event.clientX });

            

            var date = new Date(getDateFromCoord(this.options, newX));
            date.setHours(date.getHours()-1);
            //$("#cursorTitleValue").html(date.toUTCString());
            $("#cursorTitleValue").html(date.toLocaleString());
        },
        saveGanttfunData : function (stripeData) {
            var gantWidget = this;
            $.ajax({
                type: "POST",
                url: this.ganttSaveDataUrl,
                data: JSON.stringify({ stripe: stripeData }),
                async: false,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    //gantWidget.onDataObtain(data.d);
                    //gantWidget._refresh();

                },
                error: function (r) {
                    gantWidget.onDataFailed();
                }
            });
        },
        loadGanttData: function () {
            var gantWidget = this;
            //var param = { startDate: null, endDate: null };    
            var param = { startDate: this.options.startTs, endDate: this.options.endTs };            
            
            $.ajax({
                type: "POST",
                url: gantWidget.ganttLoadDataUrl,                
                data: JSON.stringify(param),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    var obj = data.d;
                    gantWidget.onDataObtain(obj);
                },
                error: function (r) {
                    gantWidget.onDataFailed(r);
                }
            });
        },
        /*Events*/
        onDataObtain: function (data) {

            var incomeObject = JSON.parse(data);
            this.GanttData = incomeObject.data;
            this._refresh();
            //this._trigger("refresh");
        },
        onDataFailed: function (error) {
            alert(error.statusText);
        },
        reDraw : function()
        {
            this._destroy();
            this._create();
        },
        // events bound via _on are removed automatically
        // revert other modifications here
        _destroy: function () {
            // remove generated elements
            this.titleArea.remove();
            this.drawArea.remove();
            this.toolBar.remove();
            this.timeLine.remove();
            this.element
              .removeClass("GanttArea")
              .enableSelection()
              .css("background-color", "transparent");
        }
        });
    //$(".GanttArea").gantt({});
});



function createToolBar()
{
    var $toolBar = $("<div>", { "class": "toolBar" });
    $("<span>", {"class": "BarCell fa fa-plus fa-2x", "id": "addItem"}).appendTo($toolBar);
    $("<span>", {"class": "BarCell fa fa-cog fa-2x", "id": "openSetting"}).appendTo($toolBar);
    $("<span>", {"class": "BarCell fa fa-arrow-right fa-2x", "id": "shiftRight"}).appendTo($toolBar);
    $("<span>", {"class": "BarCell fa fa-arrow-left fa-2x", "id": "shiftLeft"}).appendTo($toolBar);
    $("<span>", {"class": "BarCell fa fa-search-minus fa-2x", "id": "zoomOut"}).appendTo($toolBar);
    $("<span>", { "class": "BarCell fa fa-search-plus fa-2x", "id": "zoomIn" }).appendTo($toolBar);
    //$("<span>", { "class": "BarCell fa fa-floppy-o fa-2x", "id": "save" }).appendTo($toolBar);
    return $toolBar;
}

function createRectangle(x, y, classes, width, id, title)
{
    var rect = $(document.createElementNS(svgns, "rect")).attr({
        x: x,
        y: y,
        width: width,
        id: "str"+id,
        title: title,
        class: classes,
        height: 30,
        stripeId: id
    });
    return rect;
}

function createLine(sX, sY, eX, eY, classes) {
    var line = $(document.createElementNS(svgns, "line")).attr({
        x1: sX,
        y1: sY,
        x2: eX,
        y2: eY,
        class: classes
    });
    return line;
}

function createText(x, y, desc, classes)
{
    var text = $(document.createElementNS(svgns, "text")).attr({
        x: x,
        y: y,
        class: classes
    });   
    text.attr("title", desc);

    var t = document.createTextNode(desc);
    text.append(t);
    return text;
}

function createDrawingBorder(borderArea, options)
{
    var rows = options.rowsNum;
    var ey = rows * options.rowHeight + options.offsetVertical;
    var leftBorderLines = createLine(options.offsetLeft + 1, options.offsetVertical, options.offsetLeft + 1, ey, "borderLine");
    leftBorderLines.appendTo(borderArea);

    var rightBorderLines = createLine(options.width - 1, options.offsetVertical, options.width - 1, ey, "borderLine");
    rightBorderLines.appendTo(borderArea);

    var topBorderLines = createLine(options.offsetLeft, options.offsetVertical, options.width-1, options.offsetVertical, "borderLine");
    topBorderLines.appendTo(borderArea);
}

function createGridLines(drawArea, options) {
    var gridLine = createLine(options.offsetLeft + 137, options.offsetVertical, options.offsetLeft + 137, options.rowsNum * options.rowHeight, "gridLine");
    gridLine.appendTo(drawArea);
}

function createOptionsDialog() {
    var optionsDialog = $('<div>', {
        "id": "optionsDialog",
        "title": "Options"
    })
    .append("<p><input type='checkbox' id='showGridChckbx' name='showGrid'>Zobrazit mřížku <p/>")
    .append("<p><input type='checkbox' id='enableGridSnap' name='enableGridSnap'>Přichytávání ke mřížce<p/>")
    .append("<p><input type='checkbox' id='showMouseCursorChckbx' name='showMouseCursor'>Zobrazit kurzor <p/>")
    .append("<p><input type='checkbox' id='showStripeTitleChckbx' name='showStripeTitle'>Zobrazit popisky pruhů<p/>");
    return optionsDialog;
}

function moveStripe($rect, x, y) {
    $rect.attr('x', x);
    $rect.attr('y', y);
}

function moveText($stripeTitle, x,y) {
    $stripeTitle.attr("x", x);
    $stripeTitle.attr("y", y);
}

//compute x for ace coord 
function getXCoord(options, posTime) {
    var x = -1; //-1 mimo v levo, -999 mimo v pravo
    if (posTime >= options.viewEndTs)
        x = -999;
    if (posTime <= options.viewStartTs)
        x = -1;
    if (posTime < options.viewEndTs && posTime > options.viewStartTs)
    {
        var timeDiff = posTime - options.viewStartTs;
        var aceLength = options.viewEndTs - options.viewStartTs;

        if (timeDiff <= options.viewEndTs && timeDiff > 0 && aceLength > 0) {
            x = ((options.aceCoordLength / aceLength) * timeDiff) + options.offsetLeft;
        }
    }
    return Math.floor(x);
}

//compute date  from ace coord 
function getDateFromCoord(options, position)
{
    var x = 0;    
    var coordDiff = position - options.offsetLeft;
    var aceLength = options.viewEndTs - options.viewStartTs;
    x = ((aceLength / options.aceCoordLength) * coordDiff) + options.viewStartTs;
    return Math.floor(x);
}



function getAceUnits(options, timeLine, drawArea)
{
    var startTs = options.viewStartTs;
    var endTs = options.viewEndTs;

    //test
    var length = options.aceCoordLength;
    var timeDiff = endTs - startTs;

    timeUnits = {                                    
        years: 943488000000,
        months: 2592000000,
        days: 86400000,
        hours: 3600000,
        minutes: 60000,
        seconds: 1000
    }

    var unit = null;
    for (unit in timeUnits)
    {
        if((timeDiff / timeUnits[unit]) >= 3) { break; }
    }

    //naleznuto jednotky celkovyp ocet dilku nebo velikost jednoho 
    var unitsCount = Math.round(timeDiff / timeUnits[unit]);

    //konec prvniho casoveho useku
    var eX = (Math.round(startTs / (timeUnits[unit]))) * (timeUnits[unit]);

    var eCX = getXCoord(options, eX) - options.offsetLeft;
    var sCX = 0;

    if (eCX < 0) { eCX = 0 }

    var blockWidth = eCX - sCX;

    var dt = new Date(startTs);

    if (blockWidth > 0)
    {
        $("<div>", { "class": "timeBar", width: blockWidth }).html(dt.getDate()).appendTo(timeLine.find(".botTimeLine").eq(0));
    }    

    var aggrTime = eX;
    var aggrCX = eCX;

    while (aggrTime < endTs)
    {
        if (options.showGrid)
        {
            var gridLine = createLine(options.offsetLeft + aggrCX, options.offsetVertical, options.offsetLeft + aggrCX, options.rowsNum * options.rowHeight, "gridLine");
            gridLine.appendTo(drawArea);
        }

        aggrTime += timeUnits[unit];        
        
        aggrCX = getXCoord(options, aggrTime) - options.offsetLeft;

        if (aggrCX < 0) { aggrCX = options.aceCoordLength; }

        blockWidth = aggrCX - eCX;

        dt = new Date(eX);

        if (blockWidth > 0)
        {
            var titleNumber = -1;

            switch (unit) {
                case "years": titleNumber = dt.getYear(); break;
                case "months": titleNumber = dt.getMonth(); break;
                case "days": titleNumber = dt.getDate(); break;
                case "hours": dt = new Date(eX - (60*60*1000)); titleNumber = dt.getHours(); break;
                case "minutes": titleNumber = dt.getMinutes(); break;
                case "seconds": titleNumber = dt.getSeconds(); break;
                default: titleNumber = dt.getDate();
            }

            $("<div>", { "class": "timeBar", width: blockWidth }).html(titleNumber).appendTo(timeLine.find(".botTimeLine").eq(0));
        }        

        eCX = aggrCX;
        eX = aggrTime;        
    }
    //koncovy blok dodelat 

    return unitsCount;
    //return unit;
}

var toBoolean = function (val)
{
    var res = false;
    res = (val == "true" || val == "True")
    return res;
}