// @(#)root/gl:$Id$
// Author:  Matevz Tadel, Feb 2007

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TGLSelectBuffer.h"
#include "TGLSelectRecord.h"
#include <TMath.h>

#include <algorithm>

//______________________________________________________________________________
//
// Encapsulates OpenGL select buffer.
// Provides sorting of the results based on z-coordinate of the
// selection hit and can fill the TGLSelectRecordBase records.

Int_t TGLSelectBuffer::fgMaxBufSize = 1 << 20; // 1MByte

//______________________________________________________________________________
TGLSelectBuffer::TGLSelectBuffer() :
   fBufSize  (1024),
   fBuf      (new UInt_t [fBufSize]),
   fNRecords (-1)
{
   // Constructor.
}

//______________________________________________________________________________
TGLSelectBuffer::~TGLSelectBuffer()
{
   // Destructor.

   delete [] fBuf;
}

//______________________________________________________________________________
Bool_t TGLSelectBuffer::CanGrow()
{
   //static: return true if current buffer is smaller than the max buffer size
   return fBufSize < fgMaxBufSize;
}

//______________________________________________________________________________
void TGLSelectBuffer::Grow()
{
   // Increase size of the select buffer.

   delete [] fBuf;
   fBufSize = TMath::Min(2*fBufSize, fgMaxBufSize);
   fBuf = new UInt_t[fBufSize];
}

//______________________________________________________________________________
void TGLSelectBuffer::ProcessResult(Int_t glResult)
{
   // Process result of GL-selection: sort the hits by their minimum
   // z-coordinate.

   // The '-1' case should be handled on the caller side.
   // Here we just assume no hits were recorded.

   if (glResult < 0)
      glResult = 0;

   fNRecords = glResult;
   fSortedRecords.resize(fNRecords);

   if (fNRecords > 0)
   {
      Int_t  i;
      UInt_t* buf = fBuf;
      for (i = 0; i < fNRecords; ++i)
      {
         fSortedRecords[i].first  = buf[1]; // minimum depth
         fSortedRecords[i].second = buf;    // record address
         buf += 3 + buf[0];
      }
      std::sort(fSortedRecords.begin(), fSortedRecords.end());
   }
}

//______________________________________________________________________________
Int_t TGLSelectBuffer::SelectRecord(TGLSelectRecordBase& rec, Int_t i)
{
   // Fill select record rec with data on (sorted) position i.
   // Returns depth of name-stack for this record.

   rec.Set(fSortedRecords[i].second);
   return rec.GetN();
}
 TGLSelectBuffer.cxx:1
 TGLSelectBuffer.cxx:2
 TGLSelectBuffer.cxx:3
 TGLSelectBuffer.cxx:4
 TGLSelectBuffer.cxx:5
 TGLSelectBuffer.cxx:6
 TGLSelectBuffer.cxx:7
 TGLSelectBuffer.cxx:8
 TGLSelectBuffer.cxx:9
 TGLSelectBuffer.cxx:10
 TGLSelectBuffer.cxx:11
 TGLSelectBuffer.cxx:12
 TGLSelectBuffer.cxx:13
 TGLSelectBuffer.cxx:14
 TGLSelectBuffer.cxx:15
 TGLSelectBuffer.cxx:16
 TGLSelectBuffer.cxx:17
 TGLSelectBuffer.cxx:18
 TGLSelectBuffer.cxx:19
 TGLSelectBuffer.cxx:20
 TGLSelectBuffer.cxx:21
 TGLSelectBuffer.cxx:22
 TGLSelectBuffer.cxx:23
 TGLSelectBuffer.cxx:24
 TGLSelectBuffer.cxx:25
 TGLSelectBuffer.cxx:26
 TGLSelectBuffer.cxx:27
 TGLSelectBuffer.cxx:28
 TGLSelectBuffer.cxx:29
 TGLSelectBuffer.cxx:30
 TGLSelectBuffer.cxx:31
 TGLSelectBuffer.cxx:32
 TGLSelectBuffer.cxx:33
 TGLSelectBuffer.cxx:34
 TGLSelectBuffer.cxx:35
 TGLSelectBuffer.cxx:36
 TGLSelectBuffer.cxx:37
 TGLSelectBuffer.cxx:38
 TGLSelectBuffer.cxx:39
 TGLSelectBuffer.cxx:40
 TGLSelectBuffer.cxx:41
 TGLSelectBuffer.cxx:42
 TGLSelectBuffer.cxx:43
 TGLSelectBuffer.cxx:44
 TGLSelectBuffer.cxx:45
 TGLSelectBuffer.cxx:46
 TGLSelectBuffer.cxx:47
 TGLSelectBuffer.cxx:48
 TGLSelectBuffer.cxx:49
 TGLSelectBuffer.cxx:50
 TGLSelectBuffer.cxx:51
 TGLSelectBuffer.cxx:52
 TGLSelectBuffer.cxx:53
 TGLSelectBuffer.cxx:54
 TGLSelectBuffer.cxx:55
 TGLSelectBuffer.cxx:56
 TGLSelectBuffer.cxx:57
 TGLSelectBuffer.cxx:58
 TGLSelectBuffer.cxx:59
 TGLSelectBuffer.cxx:60
 TGLSelectBuffer.cxx:61
 TGLSelectBuffer.cxx:62
 TGLSelectBuffer.cxx:63
 TGLSelectBuffer.cxx:64
 TGLSelectBuffer.cxx:65
 TGLSelectBuffer.cxx:66
 TGLSelectBuffer.cxx:67
 TGLSelectBuffer.cxx:68
 TGLSelectBuffer.cxx:69
 TGLSelectBuffer.cxx:70
 TGLSelectBuffer.cxx:71
 TGLSelectBuffer.cxx:72
 TGLSelectBuffer.cxx:73
 TGLSelectBuffer.cxx:74
 TGLSelectBuffer.cxx:75
 TGLSelectBuffer.cxx:76
 TGLSelectBuffer.cxx:77
 TGLSelectBuffer.cxx:78
 TGLSelectBuffer.cxx:79
 TGLSelectBuffer.cxx:80
 TGLSelectBuffer.cxx:81
 TGLSelectBuffer.cxx:82
 TGLSelectBuffer.cxx:83
 TGLSelectBuffer.cxx:84
 TGLSelectBuffer.cxx:85
 TGLSelectBuffer.cxx:86
 TGLSelectBuffer.cxx:87
 TGLSelectBuffer.cxx:88
 TGLSelectBuffer.cxx:89
 TGLSelectBuffer.cxx:90
 TGLSelectBuffer.cxx:91
 TGLSelectBuffer.cxx:92
 TGLSelectBuffer.cxx:93
 TGLSelectBuffer.cxx:94
 TGLSelectBuffer.cxx:95
 TGLSelectBuffer.cxx:96
 TGLSelectBuffer.cxx:97