//-----------------------------------------------------------------------------
float vktraceviewer_QTimelineView::scalePositionHorizontally(uint64_t value) const
{
    uint64_t shiftedValue = value - m_rawStartTime;
    float offset = scaleDurationHorizontally(shiftedValue);

    return offset;
}
//-----------------------------------------------------------------------------
void vktraceviewer_QTimelineView::updateGeometries()
{
    uint64_t duration = m_rawEndTime - m_rawStartTime;
    int hMax = scaleDurationHorizontally(duration) + 2*m_margin - viewport()->width();
    horizontalScrollBar()->setRange(0, qMax(0, hMax));
    horizontalScrollBar()->setPageStep(viewport()->width());
    horizontalScrollBar()->setSingleStep(1);
}
//-----------------------------------------------------------------------------
void vktraceviewer_QTimelineView::drawBaseTimelines(QPainter* painter, const QRect& rect, const QList<uint32_t> &threadList)
{
    int numThreads = threadList.count();

    painter->save();
    QFont font = painter->font();
    int fontHeight = qMin((int)(m_threadHeight * 0.3), font.pointSize());
    font.setPointSize(fontHeight);
    painter->setFont(font);

    for (int i = 0; i < numThreads; i++)
    {
        int threadTop = (i*m_threadHeight);

        painter->drawText(0, threadTop + fontHeight, QString("Thread %1").arg(threadList[i]));

        // draw the timeline in the middle of this thread's area
        int lineStart = m_margin - horizontalOffset();
        int lineEnd = lineStart + scaleDurationHorizontally(m_lineLength);
        int lineY = threadTop + m_threadHeight/2;
        painter->drawLine(lineStart, lineY, lineEnd, lineY);
    }
    painter->restore();
}
void vogleditor_QTimelineView::drawTimelineItem(QPainter* painter, vogleditor_timelineItem *pItem, int height, float& minimumOffset)
{
   float duration = pItem->getDuration();
   if (duration < 0)
   {
      return;
   }

   painter->save();
   if (pItem->isMarker())
   {
      painter->setBrush(m_triangleBrush);
      painter->setPen(m_trianglePen);

      float offset = scalePositionHorizontally(pItem->getBeginTime());
      painter->drawLine(QLineF(offset, -height, offset, height));
   }
   else
   {
       // only draw if the item will extend beyond the minimum offset
       float leftOffset = scalePositionHorizontally(pItem->getBeginTime());
       float scaledWidth = scaleDurationHorizontally(duration);
       if (minimumOffset < leftOffset + scaledWidth)
       {
           float durationRatio = duration / m_maxItemDuration;
           int intensity = std::min(255, (int)(durationRatio * 255.0f));
           //   painter->setBrush(*(pItem->getBrush()));
           QColor color(intensity, 255-intensity, 0);
           painter->setBrush(QBrush(color));
           painter->setPen(color);

           // Clamp the item so that it is 1 pixel wide.
           // This is intentionally being done before updating the minimum offset
           // so that small items after the current item will not be drawn
           if (scaledWidth < 1)
           {
               scaledWidth = 1;
           }

           // update minimum offset
           minimumOffset = leftOffset + scaledWidth;

           // draw the colored box that represents this item
           QRectF rect;
           rect.setLeft(leftOffset);
           rect.setTop(-height/2);
           rect.setWidth(scaledWidth);
           rect.setHeight(height);
           painter->drawRect(rect);

           // now draw all children
           int numChildren = pItem->childCount();
           for (int c = 0; c < numChildren; c++)
           {
               drawTimelineItem(painter, pItem->child(c), height-1, minimumOffset);
           }
       }
   }

   painter->restore();
}
void vogleditor_QTimelineView::drawTimelineItem(QPainter *painter, vogleditor_timelineItem *pItem, int height, double &minimumOffset)
{
    float duration = pItem->getDuration();
    if (duration < 0)
    {
        return;
    }
    if (pItem->isMarker()) // frame marker
    {
        painter->setBrush(m_triangleBrushWhite);
        painter->setPen(m_trianglePen);

        float offset = scalePositionHorizontally(pItem->getBeginTime());
        painter->drawLine(QLineF(offset, -height, offset, height));
    }
    else
    {
        // only draw if the item will extend beyond the minimum offset and it is on-screen
        double leftOffset = scalePositionHorizontally(pItem->getBeginTime());
        double scaledWidth = scaleDurationHorizontally(duration);
        double rightOffset = leftOffset + scaledWidth;
        if (minimumOffset < rightOffset && rightOffset>m_scroll && leftOffset<m_scroll+width() )
        {
            // Set brush fill color
            if (pItem->getBrush())
            {
                painter->setBrush(*(pItem->getBrush()));
            }
            else // create brush with color relative to time duration of apicall
            {
                float durationRatio = duration / m_maxItemDuration;
                int intensity = std::min(255, (int)(durationRatio * 255.0f));
                QColor color(intensity, 255 - intensity, 0);
                painter->setBrush(QBrush(color));
            }
            // don't draw boundary. It can add an extra pixel to rect width
            painter->setPen(Qt::NoPen);

            // Clamp the item so that it is 1 pixel wide.
            // This is intentionally being done before updating the minimum offset
            // so that small items after the current item will not be drawn
            if (scaledWidth < 1)
            {
                scaledWidth = 1;
            }

            // update minimum offset
            minimumOffset = leftOffset + scaledWidth;
            int startTimePx = leftOffset - m_roundoff;
            int durationPx = scaledWidth + m_roundoff;

            // draw the colored box that represents this item
            QRect rect;
            rect.setLeft(startTimePx);
            rect.setTop(-height / 2);
            rect.setWidth(durationPx);
            rect.setHeight(height);
            painter->drawRect(rect);

            //Add the position of this item to the timelineItemPosCache for use by itemUnderPos().
            timelineItemPos itemPos;
            itemPos.pItem=pItem;
            itemPos.leftOffset=startTimePx;
            itemPos.rightOffset=startTimePx+durationPx;
            m_timelineItemPosCache.append(itemPos);
        }

        // If only State/Render groups to display, we're done (if debug groups
        // are checked continue to draw individual apicalls)
        //
        // TODO: test replacing following if-block check with just:
        //       if (pItem->isGroupItem())
        if (g_settings.group_state_render_stat() && !g_settings.group_debug_marker_in_use())
        {
            return;
        }
        // now draw all children
        int numChildren = pItem->childCount();
        for (int c = 0; c < numChildren; c++)
        {
            drawTimelineItem(painter, pItem->child(c), height - 1, minimumOffset);
        }
    }

}