text: #include "hicubeit.h"
  
  #include "TextFile.h"
  #include "Pvl.h"
  #include "Cube.h"
  #include "OriginalLabel.h"
  #include "ProgramLauncher.h"
  #include <QString>
  
  using namespace std;
  
  namespace Isis {
  
    void hicubeit(UserInterface &ui) {
      QString redFile = ui.GetFileName("RED");
      QString irFile  = ui.GetFileName("IR");
      QString bgFile  = ui.GetFileName("BG");
  
      FileName tempFile = FileName::createTempFile("$TEMPORARY/hicubeit.temp.lis");
      TextFile tf;
      tf.Open(tempFile.expanded(), "output");
      tf.PutLine(irFile + "\n");
      tf.PutLine(redFile + "\n");
      tf.PutLine(bgFile + "\n");
      tf.Close();
  
      QString parameters = QString(" FROMLIST = ")    + tempFile.expanded() +
                          QString(" TO = ")      + ui.GetFileName("TO") +
                          QString(" PROPLAB = ") + redFile;
      ProgramLauncher::RunIsisProgram("cubeit", parameters);
      remove(tempFile.expanded().toLatin1().data());
  
      // Get the instrument group from each file
      Pvl redLab(redFile);
      Pvl irLab(irFile);
      Pvl bgLab(bgFile);
  
      PvlGroup redInst = redLab.findGroup("Instrument", Pvl::Traverse);
      PvlGroup irInst  = irLab.findGroup("Instrument", Pvl::Traverse);
      PvlGroup bgInst  = bgLab.findGroup("Instrument", Pvl::Traverse);
  
      // Error check to make sure the proper ccds are stacked
      if((int)redInst["CpmmNumber"] == 5) {
        if(((int)irInst["CpmmNumber"] != 6) || ((int)bgInst["CpmmNumber"] != 4)) {
          QString msg = "You can only stack color images with RED4, IR10, and BG12 ";
          msg += "or RED5, IR11, and BG13";
          throw IException(IException::User, msg, _FILEINFO_);
        }
      }
      else if((int)redInst["CpmmNumber"] == 8) {
        if(((int)irInst["CpmmNumber"] != 7) || ((int)bgInst["CpmmNumber"] != 9)) {
          QString msg = "You can only stack color images with RED4, IR10, and BG12 ";
          msg += "or RED5, IR11, and BG13";
          throw IException(IException::User, msg, _FILEINFO_);
        }
      }
      else {
        QString msg = "You can only stack color images with RED4, IR10, and BG12 ";
        msg += "or RED5, IR11, and BG13";
        throw IException(IException::User, msg, _FILEINFO_);
      }
  
      // Concatenate all the source products into one keyword
      PvlKeyword sourceProductId("SourceProductId");
      sourceProductId += (QString)bgInst["StitchedProductIds"][0];
      if(bgInst["StitchedProductIds"].size() > 1) {
        sourceProductId += (QString)bgInst["StitchedProductIds"][1];
      }
      sourceProductId += (QString)redInst["StitchedProductIds"][0];
      if(redInst["StitchedProductIds"].size() > 1) {
        sourceProductId += (QString)redInst["StitchedProductIds"][1];
      }
      sourceProductId += (QString)irInst["StitchedProductIds"][0];
      if(irInst["StitchedProductIds"].size() > 1) {
        sourceProductId += (QString)irInst["StitchedProductIds"][1];
      }
  
      // Get min start and max stop time
      PvlKeyword startTime = redInst["StartTime"];
      PvlKeyword stopTime  = redInst["StopTime"];
      PvlKeyword startClk  = redInst["SpacecraftClockStartCount"];
      PvlKeyword stopClk   = redInst["SpacecraftClockStopCount"];
  
      if((QString) irInst["StartTime"] < (QString)startTime) {
        startTime = irInst["StartTime"];
      }
      if((QString) bgInst["StartTime"] < (QString)startTime) {
        startTime = bgInst["StartTime"];
      }
  
      if((QString) irInst["StopTime"] > (QString)stopTime) {
        stopTime = irInst["StopTime"];
      }
      if((QString) bgInst["StopTime"] > (QString)stopTime) {
        stopTime = bgInst["StopTime"];
      }
  
      if((QString) irInst["SpacecraftClockStartCount"] < (QString)startClk) {
        startClk = irInst["SpacecraftClockStartCount"];
      }
      if((QString) bgInst["SpacecraftClockStartCount"] < (QString)startClk) {
        startClk = bgInst["SpacecraftClockStartCount"];
      }
  
      if((QString) irInst["SpacecraftClockStopCount"] > (QString)stopClk) {
        stopClk = irInst["SpacecraftClockStopCount"];
      }
      if((QString) bgInst["SpacecraftClockStopCount"] > (QString)stopClk) {
        stopClk = bgInst["SpacecraftClockStopCount"];
      }
  
      // Concatenate all TDIs into one keyword
      OriginalLabel redOrgLab;
      redOrgLab.Blob::Read(redFile);
      OriginalLabel irOrgLab;
      irOrgLab.Blob::Read(irFile);
      OriginalLabel bgOrgLab;
      bgOrgLab.Blob::Read(bgFile);
  
      PvlGroup redGrp = redOrgLab.ReturnLabels().findGroup("INSTRUMENT_SETTING_PARAMETERS", Pvl::Traverse);
      PvlGroup irGrp = irOrgLab.ReturnLabels().findGroup("INSTRUMENT_SETTING_PARAMETERS", Pvl::Traverse);
      PvlGroup bgGrp = bgOrgLab.ReturnLabels().findGroup("INSTRUMENT_SETTING_PARAMETERS", Pvl::Traverse);
  
      PvlKeyword cpmmTdiFlag("cpmmTdiFlag");
      for(int i = 0; i < 14; i++) {
        cpmmTdiFlag += (QString) "";
      }
      cpmmTdiFlag[(int)redInst["CpmmNumber"]] = (QString) redGrp["MRO:TDI"];
      cpmmTdiFlag[(int)irInst["CpmmNumber"]] = (QString) irGrp["MRO:TDI"];
      cpmmTdiFlag[(int)bgInst["CpmmNumber"]] = (QString) bgGrp["MRO:TDI"];
  
      // Concatenate all summing modes into one keyword
      PvlKeyword cpmmSummingFlag("cpmmSummingFlag");
      for(int i = 0; i < 14; i++) {
        cpmmSummingFlag += (QString) "";
      }
      cpmmSummingFlag[(int)redInst["CpmmNumber"]] = (QString) redGrp["MRO:BINNING"];
      cpmmSummingFlag[(int)irInst["CpmmNumber"]] = (QString) irGrp["MRO:BINNING"];
      cpmmSummingFlag[(int)bgInst["CpmmNumber"]] = (QString) bgGrp["MRO:BINNING"];
  
      //Concatenate all the Special_Processing_Flag into one keyword
      PvlKeyword specialProcessingFlag("SpecialProcessingFlag");
      for(int i = 0; i < 14; i++) {
        specialProcessingFlag += (QString) "";
      }
      //keyword Special_Processing_Flag may not be present so need to test
      // if not present set to NOMINAL
      if(redInst.hasKeyword("Special_Processing_Flag")) {
        specialProcessingFlag[redInst["CpmmNumber"]] = (QString) redInst["Special_Processing_Flag"];
      }
      else {
        specialProcessingFlag[redInst["CpmmNumber"]] = "NOMINAL";
      }
      if(irInst.hasKeyword("Special_Processing_Flag")) {
        specialProcessingFlag[irInst["CpmmNumber"]] = (QString) irInst["Special_Processing_Flag"];
      }
      else {
        specialProcessingFlag[irInst["CpmmNumber"]] = "NOMINAL";
      }
      if(bgInst.hasKeyword("Special_Processing_Flag")) {
        specialProcessingFlag[bgInst["CpmmNumber"]] = (QString) bgInst["Special_Processing_Flag"];
      }
      else {
        specialProcessingFlag[bgInst["CpmmNumber"]] = "NOMINAL";
      }
      // Put them in a group
      PvlGroup mos("Mosaic");
      mos += sourceProductId;
      mos += startTime;
      mos += stopTime;
      mos += startClk;
      mos += stopClk;
      mos += cpmmTdiFlag;
      mos += cpmmSummingFlag;
      mos += specialProcessingFlag;
  
      // Add the group to the output cube
      Cube c;
      c.open(ui.GetFileName("TO"), "rw");
      c.label()->findObject("IsisCube", Pvl::Traverse).addGroup(mos);
      c.close();
    }
  }
  