/*==================================================
 * TimeMap Event Painter
 * This is just the basic Timeline event painter
 * with a few things removed and hooks for the event
 * to access its associated DOM elements.
 *==================================================
 */

/**
 * Overwrite paint function.
 */
Timeline.DurationEventPainter.prototype.paint = function() {
    var eventSource = this._band.getEventSource();
    if (eventSource == null) {
        return;
    }
    
    if (this._highlightLayer != null) {
        this._band.removeLayerDiv(this._highlightLayer);
    }
    this._highlightLayer = this._band.createLayerDiv(105);
    this._highlightLayer.setAttribute("name", "event-highlights");
    this._highlightLayer.style.display = "none";
    
    if (this._eventLayer != null) {
        this._band.removeLayerDiv(this._eventLayer);
    }
    this._eventLayer = this._band.createLayerDiv(110);
    this._eventLayer.setAttribute("name", "events");
    this._eventLayer.style.display = "none";
    
    var minDate = this._band.getMinDate();
    var maxDate = this._band.getMaxDate();
    
    var doc = this._timeline.getDocument();
    
    var p = this;
    var eventLayer = this._eventLayer;
    var highlightLayer = this._highlightLayer;
    
    var showText = this._showText;
    var theme = this._params.theme;
    var eventTheme = theme.event;
    var trackOffset = eventTheme.track.offset;
    var trackHeight = ("trackHeight" in this._params) ? this._params.trackHeight : eventTheme.track.height;
    var trackGap = ("trackGap" in this._params) ? this._params.trackGap : eventTheme.track.gap;
    
    
    var appendIcon = function(evt, div) {
        var icon = evt.getIcon();
        var img = Timeline.Graphics.createTranslucentImage(
            doc, icon != null ? icon : eventTheme.instant.icon
        );
        div.appendChild(img);
        div.style.cursor = "pointer";
        
        Timeline.DOM.registerEvent(div, "mousedown", function(elmt, domEvt, target) {
            p._showBubble(0,0, evt);
        });
    };
    var createHighlightDiv = function(highlightIndex, startPixel, length, highlightOffset, highlightWidth) {
        if (highlightIndex >= 0) {
            var color = eventTheme.highlightColors[Math.min(highlightIndex, eventTheme.highlightColors.length - 1)];
            
            var div = doc.createElement("div");
            div.style.position = "absolute";
            div.style.overflow = "hidden";
            div.style.left = (startPixel - 3) + "px";
            div.style.width = (length + 6) + "px";
            div.style.top = highlightOffset + "em";
            div.style.height = highlightWidth + "em";
            div.style.background = color;
            //Timeline.Graphics.setOpacity(div, 50);
            
            highlightLayer.appendChild(div);
        }
    };
    
    // Create the div for an instant event
    // Can remain as is for now
    var createInstantDiv = function(evt, startPixel, endPixel, streamOffset, highlightIndex, highlightOffset, highlightWidth) {
        
        var div = doc.createElement("div");
        div.style.position = "absolute";
        div.style.overflow = "hidden";
        // set event class
        div.setAttribute("class", "tm-instant-event");
        eventLayer.appendChild(div);
        
        var foreground = evt.getTextColor();
        var background = evt.getColor();
        
        var realign = -8; // shift left so that icon is centered on startPixel
        var length = 16;
        if (showText) {
            div.style.width = eventTheme.label.width + "px";
            div.style.color = foreground != null ? foreground : eventTheme.label.outsideColor;
            
            appendIcon(evt, div);
            div.appendChild(doc.createTextNode(evt.getText()));
        } else {
            if (p._showLineForNoText) {
                div.style.width = "1px";
                div.style.borderLeft = "1px solid " + (background != null ? background : eventTheme.instant.lineColor);
                realign = 0; // no shift
                length = 1;
            } else {
                appendIcon(evt, div);
            }
        }
        
        div.style.top = streamOffset;
        div.style.height = trackHeight + "em";
        div.style.left = (startPixel + realign) + "px";
        
        createHighlightDiv(highlightIndex, (startPixel + realign), length, highlightOffset, highlightWidth);
        // attach div to event
        evt._div = div;
        // attach info to event
        evt._startPixel = startPixel;
        evt._endPixel = endPixel;
    };
    
    // create the div for a duration event
    var createDurationDiv = function(evt, startPixel, endPixel, streamOffset, highlightIndex, highlightOffset, highlightWidth) {
        var attachClickEvent = function(elmt) {
            elmt.style.cursor = "pointer";
            Timeline.DOM.registerEvent(elmt, "mousedown", function(elmt, domEvt, target) {
                p._showBubble(0,0, evt);
            });
        };
    
        var addEventLabel = function(text, startPixel, endPixel, streamOffset) {
            var divLabel = doc.createElement("div");
            divLabel.style.position = "absolute";
            // set event class
            divLabel.setAttribute("class", "tm-duration-event-label");
            
            divLabel.style.top = streamOffset;
            divLabel.style.height = trackHeight + "em";
            divLabel.style.left =  startPixel + "px";
            divLabel.style.color = foreground != null ? foreground : (outside ? eventTheme.label.outsideColor : eventTheme.label.insideColor);
            divLabel.style.overflow = "hidden";
            divLabel.appendChild(doc.createTextNode(text));
            
            eventLayer.appendChild(divLabel);
            attachClickEvent(divLabel);
        }
        
        var length = Math.max(endPixel - startPixel, 1);
        
        var foreground = evt.getTextColor();
        var outside = true;
        if (startPixel <= endPixel) {
            outside = !(length > eventTheme.label.width);
            
            div = doc.createElement("div");
            div.style.position = "absolute";
            div.style.overflow = "hidden";
            // set event class
            div.setAttribute("class", "tm-duration-event");
            
            div.style.top = streamOffset;
            div.style.height = trackHeight + "em";
            div.style.left = startPixel + "px";
            div.style.width = length + "px";
            
            var background = evt.getColor();
            
            div.style.background = background != null ? background : eventTheme.duration.color;
            if (eventTheme.duration.opacity < 100) {
                Timeline.Graphics.setOpacity(div, eventTheme.duration.opacity);
            }
            
            eventLayer.appendChild(div);
        } else {
            var temp = startPixel;
            startPixel = endPixel;
            endPixel = temp;
        }
        attachClickEvent(div);
            
        
        
        /*
         * Add periods if available
         */
        if (evt.periods) {
            var dateParser = evt.dateParser;
            var start, end, startPx, endPx, offset, pdiv;
            for (j=0; j < evt.periods.length; j++) {
                start = dateParser(evt.periods[j].start);
                end = dateParser(evt.periods[j].end);
                startPx = Math.round(p._band.dateToPixelOffset(start));
                endPx = Math.round(p._band.dateToPixelOffset(end));
                offset = Math.max((startPx - startPixel), 0);
                width = Math.max((endPx - startPixel), 0) - offset;
                
                pdiv = doc.createElement("div");
                pdiv.style.position = "absolute";
                pdiv.style.background = "#000";
                pdiv.style.left = offset + "px";
                pdiv.style.width = width + "px";
                pdiv.style.height = trackHeight + "em";
                if (showText && width > 100)
                    addEventLabel(evt.getText() + " (" + evt.periods[j].title + ")",
                                  Math.max(startPx, startPixel), endPx, streamOffset);
                var opacity = (parseInt(evt.periods[j].id) % 3) * 10;
                Timeline.Graphics.setOpacity(pdiv, opacity);
                div.appendChild(pdiv);
            }
        } else {
            if (showText) addEventLabel(evt.getText(), startPixel, endPixel, streamOffset);
        }
        
        createHighlightDiv(highlightIndex, startPixel, endPixel - startPixel, highlightOffset, highlightWidth);
        // attach divs to event
        evt._div = div;
        // attach info to event
        evt._startPixel = startPixel;
        evt._endPixel = endPixel;
    };
        
    var createEventDiv = function(evt, highlightIndex) {
        var startDate = evt.getStart();
        var endDate = evt.getEnd();
        
        var startPixel = Math.round(p._band.dateToPixelOffset(startDate));
        var endPixel = Math.round(p._band.dateToPixelOffset(endDate));
        
        var streamOffset = (trackOffset + 
            p._layout.getTrack(evt) * (trackHeight + trackGap));
            
        if (evt.isInstant()) {
            createInstantDiv(evt, startPixel, endPixel, streamOffset + "em", 
                highlightIndex, streamOffset - trackGap, trackHeight + 2 * trackGap);
        } else {
            createDurationDiv(evt, startPixel, endPixel, streamOffset + "em",
                highlightIndex, streamOffset - trackGap, trackHeight + 2 * trackGap);
        }
    };
    
    var filterMatcher = (this._filterMatcher != null) ? 
        this._filterMatcher :
        function(evt) { return true; };
    var highlightMatcher = (this._highlightMatcher != null) ? 
        this._highlightMatcher :
        function(evt) { return -1; };
    
    var iterator = eventSource.getEventIterator(minDate, maxDate);
    while (iterator.hasNext()) {
        var evt = iterator.next();
        if (filterMatcher(evt)) {
            createEventDiv(evt, highlightMatcher(evt));
        }
    }
    
    this._highlightLayer.style.display = "block";
    this._eventLayer.style.display = "block";
};

/**
 * Add periods, if available, to TimeMapItems' events
 */
TimeMapItem.prototype.addPeriodsToEvent = function() {
    this.event.periods =    this.opts['periods'] ||
                            this.dataset.opts['periods'] ||
                            this.dataset.timemap.opts['periods'] ||
                            false;
    this.event.dateParser = this.dataset.opts.dateParser;
} 