bool CGridLocusColumns::SetupKit(
  wxGrid *pGrid,
  const wxString &sKitName, 
  const vector<wxString> &vs, 
  bool bILS, 
  bool bAllowAmel,
  bool bSetError,
  int *pnILScolumn,
  unsigned int *pnILSchannel)
{
  wxString sProblem;
  CPersistKitList *pKit = mainApp::GetKitList();
  const CLocusNameList *pLocus = 
    pKit->GetLocusNameList(sKitName);
  if(sKitName.IsEmpty())
  {
    sProblem = "Marker set name is not specified.";
  }
  else if(pLocus == NULL)
  {
    sProblem = "Marker set, ";
    sProblem.Append(sKitName);
    sProblem.Append(", is unknown");
  }
  else if(pLocus->size() < 1)
  {
    sProblem = "Marker set, ";
    sProblem.Append(sKitName);
    sProblem.Append(", does not have any loci");
  }
  if(!sProblem.IsEmpty())
  {
    if(bSetError)
    {
      nwxGrid::SetError(pGrid,sProblem);
    }
  }
  else
  {
    vector<unsigned int> vnChannels;
    vector<int> vnCounts;
    set<unsigned int> snChannelsUsed;
    wxFont fnBold = pGrid->GetDefaultCellFont();

    int nBeforeLoci = (int)vs.size();
    int nCols = (int)(pLocus->size()) + nBeforeLoci + BINT(bILS);
    int nRemove = 0;
    int nCol;
    int nCount = 1;
    unsigned int nChannel;
    unsigned int nLastChannel = 0;  // invalid channel name for default column
    unsigned int nILSchannel = 0;
    const CSingleKitColors *pKitColors;
    const CLocusNameChannel *plc;
    pKitColors = mainApp::GetKitColors()->GetKitColors(sKitName);

    pGrid->SetMargins(0, wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y) + 4);
    fnBold.SetWeight(wxFONTWEIGHT_BOLD);
    nwxGrid::SetColCount(pGrid,nCols);
    for(nCol = 0; nCol < nCols; nCol++)
    {
      pGrid->SetCellSize(0,nCol,1,1);
      //pGrid->SetReadOnly(0,0,true);
    }
    vector<wxString>::const_iterator itrs = vs.begin();
    for(nCol = 0; nCol < nBeforeLoci; nCol++)
    {
      pGrid->SetCellBackgroundColour(0,nCol,
        pGrid->GetGridLineColour());
      pGrid->SetCellValue(0,nCol,wxEmptyString);
      pGrid->SetColLabelValue(nCol, *itrs);
      //pGrid->SetReadOnly(0,nCol,true);
      ++itrs;
    }
    // nCol = nBeforeLoci; // redundant

    // Set up column labels

    vnCounts.reserve(CHANNEL_MAX);
    vnChannels.reserve(CHANNEL_MAX);
    for(CLocusNameList::const_iterator itr = pLocus->begin();
      itr != pLocus->end();
      ++itr)
    {
      plc = *itr;
      const wxString &sName(plc->GetName());
      if(bAllowAmel || !CLabLocus::IsAmel(sName))
      {
        nChannel = plc->GetChannel();
        if(nChannel != nLastChannel)
        {
          if(nLastChannel > 0)
          {
            vnChannels.push_back(nLastChannel);
            vnCounts.push_back(nCount);
          }
          snChannelsUsed.insert(nChannel);
          nCount = 1;
          nLastChannel = nChannel;
        }
        else
        {
          nCount++;
        }
        pGrid->SetColLabelValue(nCol,plc->GetName());
        nCol++;
      }
      else
      {
        nRemove++;
      }
    }
    if(nRemove)
    {
      nCols -= nRemove;
      nwxGrid::SetColCount(pGrid,nCols);
    }
    vnChannels.push_back(nLastChannel);
    vnCounts.push_back(nCount);
    if(bILS)
    {
      // figure out which channnel is ILS

      int nChannelCount = 
        pKit->GetChannelCount(sKitName);
      for(nChannel = (unsigned int) nChannelCount;
        nChannel > 0;
        --nChannel)
      {
        if(snChannelsUsed.find(nChannel) ==
          snChannelsUsed.end())
        {
          nILSchannel = nChannel; // unused channel, assume ILS
          if(pnILSchannel != NULL)
          {
            *pnILSchannel = nChannel;
          }
          nChannel = 1; // loop exit
        }
      }

      // ILS Column Label
      pGrid->SetColLabelValue(nCol,"ILS*");
      vnChannels.push_back(nILSchannel);
      vnCounts.push_back(1);
      if(pnILScolumn != NULL)
      {
        *pnILScolumn = nCol;
      }
    }

    // column labels are set
    pGrid->SetRowLabelValue(0,"Channel");

    // now set channel cells in top row 
    // and colors throughout the table

    size_t nSize = vnChannels.size();
    size_t i;
    nCol = nBeforeLoci;
    const CChannelColors *pChannelColors;
    wxString sLabel;
    bool bColorSet = false;

    // set cell colors and set channel numbers/names in
    // first row

    for(i = 0; i < nSize; i++)
    {
      bColorSet = false;
      nChannel = vnChannels.at(i);
      nCount = vnCounts.at(i);
      if(nCount > 1)
      {
        pGrid->SetCellSize(0,nCol,1,nCount);
      }
      if(nChannel > 0)
      {
        pChannelColors = 
          (pKitColors == NULL)
          ? NULL
          : pKitColors->GetColorChannel((unsigned int)nChannel);
        const wxChar *psDyeLabel = NULL;
        if(pChannelColors != NULL)
        {
          // int k;
          pGrid->SetCellTextColour(0,nCol,*wxWHITE);
          pGrid->SetCellBackgroundColour(
              0,nCol,pChannelColors->GetColorAnalyzed());
          psDyeLabel = (const wxChar *)(pChannelColors->GetDyeName());
          bColorSet = true;
        }
        FORMAT_CHANNEL_DYE(&sLabel,(unsigned int) nChannel, psDyeLabel);
        pGrid->SetCellFont(0,nCol,fnBold);
        pGrid->SetCellValue(0,nCol,sLabel);
        pGrid->SetCellAlignment(0,nCol,wxALIGN_CENTRE, wxALIGN_CENTRE);
      }
      else
      {
        pGrid->SetCellValue(0,nCol,wxEmptyString);
      }
      if(!bColorSet)
      {
        pGrid->SetCellTextColour(0,nCol,pGrid->GetDefaultCellTextColour());
        pGrid->SetCellBackgroundColour(
          0,nCol,pGrid->GetDefaultCellBackgroundColour());
      }
      nCol += nCount;
      nwxGrid::SetRowReadOnly(pGrid,0,true);
    }
  }
  return sProblem.IsEmpty();
}