/**
   * Generate commomn attributes for converted images.
   *
   * <p>Does NOT add ManufacturerModelName ... that should be added by caller.
   *
   * <p>Does NOT call
   * CodingSchemeIdentification.replaceCodingSchemeIdentificationSequenceWithCodingSchemesUsedInAttributeList
   * ... that should be done by caller.
   *
   * @param list
   * @param patientName
   * @param patientID
   * @param studyID
   * @param seriesNumber
   * @param instanceNumber
   * @param modality may be null
   * @param sopClass may be null
   * @throws DicomException
   * @throws NumberFormatException
   */
  public static void generateCommonAttributes(
      AttributeList list,
      String patientName,
      String patientID,
      String studyID,
      String seriesNumber,
      String instanceNumber,
      String modality,
      String sopClass)
      throws DicomException {
    UIDGenerator u = new UIDGenerator();

    {
      Attribute a = new UniqueIdentifierAttribute(TagFromName.SOPInstanceUID);
      a.addValue(u.getAnotherNewUID());
      list.put(a);
    }
    {
      Attribute a = new UniqueIdentifierAttribute(TagFromName.SeriesInstanceUID);
      a.addValue(u.getAnotherNewUID());
      list.put(a);
    }
    {
      Attribute a = new UniqueIdentifierAttribute(TagFromName.StudyInstanceUID);
      a.addValue(u.getAnotherNewUID());
      list.put(a);
    }
    {
      Attribute a = new UniqueIdentifierAttribute(TagFromName.FrameOfReferenceUID);
      a.addValue(u.getAnotherNewUID());
      list.put(a);
    }

    {
      Attribute a = new PersonNameAttribute(TagFromName.PatientName);
      a.addValue(patientName);
      list.put(a);
    }
    {
      Attribute a = new LongStringAttribute(TagFromName.PatientID);
      a.addValue(patientID);
      list.put(a);
    }
    {
      Attribute a = new DateAttribute(TagFromName.PatientBirthDate);
      list.put(a);
    }
    {
      Attribute a = new CodeStringAttribute(TagFromName.PatientSex);
      list.put(a);
    }
    {
      Attribute a = new ShortStringAttribute(TagFromName.StudyID);
      a.addValue(studyID);
      list.put(a);
    }
    {
      Attribute a = new PersonNameAttribute(TagFromName.ReferringPhysicianName);
      a.addValue("^^^^");
      list.put(a);
    }
    {
      Attribute a = new ShortStringAttribute(TagFromName.AccessionNumber);
      list.put(a);
    }
    {
      Attribute a = new IntegerStringAttribute(TagFromName.SeriesNumber);
      a.addValue(seriesNumber);
      list.put(a);
    }
    {
      Attribute a = new IntegerStringAttribute(TagFromName.InstanceNumber);
      a.addValue(instanceNumber);
      list.put(a);
    }

    {
      Attribute a = new LongStringAttribute(TagFromName.Manufacturer);
      a.addValue("PixelMed");
      list.put(a);
    }
    {
      Attribute a = new LongStringAttribute(TagFromName.DeviceSerialNumber);
      a.addValue(new java.rmi.dgc.VMID().toString());
      list.put(a);
    }
    {
      Attribute a = new LongStringAttribute(TagFromName.SoftwareVersions);
      a.addValue(VersionAndConstants.getBuildDate());
      list.put(a);
    }

    {
      Attribute a = new CodeStringAttribute(TagFromName.PatientOrientation);
      list.put(a);
    }

    {
      Attribute a = new CodeStringAttribute(TagFromName.BurnedInAnnotation);
      a.addValue("NO");
      list.put(a);
    }
    {
      Attribute a = new CodeStringAttribute(TagFromName.RecognizableVisualFeatures);
      a.addValue("NO");
      list.put(a);
    }
    {
      Attribute a = new CodeStringAttribute(TagFromName.ContentQualification);
      a.addValue("RESEARCH");
      list.put(a);
    }

    {
      Attribute a = new CodeStringAttribute(TagFromName.LossyImageCompression);
      a.addValue("00");
      list.put(a);
    }

    {
      Attribute a = new LongStringAttribute(TagFromName.PositionReferenceIndicator);
      list.put(a);
    }

    {
      java.util.Date currentDateTime = new java.util.Date();
      String currentDate = new java.text.SimpleDateFormat("yyyyMMdd").format(currentDateTime);
      String currentTime = new java.text.SimpleDateFormat("HHmmss.SSS").format(currentDateTime);
      {
        Attribute a = new DateAttribute(TagFromName.StudyDate);
        a.addValue(currentDate);
        list.put(a);
      }
      {
        Attribute a = new TimeAttribute(TagFromName.StudyTime);
        a.addValue(currentTime);
        list.put(a);
      }
      {
        Attribute a = new DateAttribute(TagFromName.SeriesDate);
        a.addValue(currentDate);
        list.put(a);
      }
      {
        Attribute a = new TimeAttribute(TagFromName.SeriesTime);
        a.addValue(currentTime);
        list.put(a);
      }
      {
        Attribute a = new DateAttribute(TagFromName.ContentDate);
        a.addValue(currentDate);
        list.put(a);
      }
      {
        Attribute a = new TimeAttribute(TagFromName.ContentTime);
        a.addValue(currentTime);
        list.put(a);
      }
      {
        Attribute a = new DateAttribute(TagFromName.InstanceCreationDate);
        a.addValue(currentDate);
        list.put(a);
      }
      {
        Attribute a = new TimeAttribute(TagFromName.InstanceCreationTime);
        a.addValue(currentTime);
        list.put(a);
      }
      {
        Attribute a = new ShortStringAttribute(TagFromName.TimezoneOffsetFromUTC);
        a.addValue(DateTimeAttribute.getTimeZone(java.util.TimeZone.getDefault(), currentDateTime));
        list.put(a);
      }
    }
    {
      Attribute a = new UniqueIdentifierAttribute(TagFromName.InstanceCreatorUID);
      a.addValue(VersionAndConstants.instanceCreatorUID);
      list.put(a);
    }

    int numberOfFrames =
        Attribute.getSingleIntegerValueOrDefault(list, TagFromName.NumberOfFrames, 1);
    int samplesPerPixel =
        Attribute.getSingleIntegerValueOrDefault(list, TagFromName.SamplesPerPixel, 1);

    if (sopClass == null) {
      // if modality were not null, could actually attempt to guess SOP Class based on modality here
      // :(
      sopClass = SOPClass.SecondaryCaptureImageStorage;
      if (numberOfFrames > 1) {
        if (samplesPerPixel == 1) {
          int bitsAllocated =
              Attribute.getSingleIntegerValueOrDefault(list, TagFromName.BitsAllocated, 1);
          if (bitsAllocated == 8) {
            sopClass = SOPClass.MultiframeGrayscaleByteSecondaryCaptureImageStorage;
          } else if (bitsAllocated == 16) {
            sopClass = SOPClass.MultiframeGrayscaleWordSecondaryCaptureImageStorage;
          } else {
            Attribute aPixelData = list.getPixelData();
            if (aPixelData instanceof OtherFloatAttribute
                || aPixelData instanceof OtherDoubleAttribute) {
              sopClass = SOPClass.ParametricMapStorage;
            }
          }
        } else if (samplesPerPixel == 3) {
          sopClass = SOPClass.MultiframeTrueColorSecondaryCaptureImageStorage;
        }
      }
    }

    if (sopClass.equals(SOPClass.ParametricMapStorage)) {
      addParametricMapFrameTypeSharedFunctionalGroup(list);
      {
        Attribute a = new CodeStringAttribute(TagFromName.ContentLabel);
        a.addValue("LABEL1");
        list.put(a);
      }
      {
        Attribute a = new LongStringAttribute(TagFromName.ContentDescription);
        list.put(a);
      }
      {
        Attribute a = new PersonNameAttribute(TagFromName.ContentCreatorName);
        list.put(a);
      }
    }

    if (SOPClass.isEnhancedMultiframeImageStorage(sopClass)) {
      if (samplesPerPixel == 1) {
        double windowWidth =
            Attribute.getSingleDoubleValueOrDefault(list, TagFromName.WindowWidth, 0);
        if (windowWidth > 0) {
          double windowCenter =
              Attribute.getSingleDoubleValueOrDefault(list, TagFromName.WindowCenter, 0);
          String voiLUTFunction =
              Attribute.getSingleStringValueOrDefault(list, TagFromName.VOILUTFunction, "LINEAR");
          FunctionalGroupUtilities.generateVOILUTFunctionalGroup(
              list, numberOfFrames, windowWidth, windowCenter, voiLUTFunction);
          list.remove(TagFromName.WindowCenter);
          list.remove(TagFromName.WindowWidth);
          list.remove(TagFromName.VOILUTFunction);
        }
      }

      double rescaleSlope =
          Attribute.getSingleDoubleValueOrDefault(list, TagFromName.RescaleSlope, 0);
      if (rescaleSlope > 0) {
        double rescaleIntercept =
            Attribute.getSingleDoubleValueOrDefault(list, TagFromName.RescaleIntercept, 0);
        String rescaleType =
            Attribute.getSingleStringValueOrDefault(list, TagFromName.RescaleType, "US");
        FunctionalGroupUtilities.generatePixelValueTransformationFunctionalGroup(
            list, numberOfFrames, rescaleSlope, rescaleIntercept, rescaleType);
        list.remove(TagFromName.RescaleSlope);
        list.remove(TagFromName.RescaleIntercept);
        list.remove(TagFromName.RescaleType);
      }

      // four values required
      {
        Attribute a = new CodeStringAttribute(TagFromName.ImageType);
        a.addValue("DERIVED");
        a.addValue("PRIMARY");
        a.addValue("");
        a.addValue("");
        list.put(a);
      }
    } else {
      // two values will usually do
      {
        Attribute a = new CodeStringAttribute(TagFromName.ImageType);
        a.addValue("DERIVED");
        a.addValue("PRIMARY");
        list.put(a);
      }
    }

    if (SOPClass.isMultiframeSecondaryCaptureImageStorage(sopClass)) {
      if (list.get(TagFromName.PerFrameFunctionalGroupsSequence) != null) {
        {
          AttributeTagAttribute a = new AttributeTagAttribute(TagFromName.FrameIncrementPointer);
          a.addValue(TagFromName.PerFrameFunctionalGroupsSequence);
          list.put(a);
        }
      } else {
        if (numberOfFrames > 1) {
          {
            AttributeTagAttribute a = new AttributeTagAttribute(TagFromName.FrameIncrementPointer);
            a.addValue(TagFromName.PageNumberVector);
            list.put(a);
          }
          {
            Attribute a = new IntegerStringAttribute(TagFromName.PageNumberVector);
            for (int page = 1; page <= numberOfFrames; ++page) {
              a.addValue(page);
            }
            list.put(a);
          }
        }
      }
    }

    System.err.println(
        "CommonConvertedAttributeGeneration.generateCommonAttributes(): SOP Class = " + sopClass);
    {
      Attribute a = new UniqueIdentifierAttribute(TagFromName.SOPClassUID);
      a.addValue(sopClass);
      list.put(a);
    }

    if (SOPClass.isSecondaryCaptureImageStorage(sopClass)) {
      {
        Attribute a = new CodeStringAttribute(TagFromName.ConversionType);
        a.addValue("WSD");
        list.put(a);
      }
    }

    if (modality == null) {
      // could actually attempt to guess modality based on SOP Class here :(
      modality = "OT";
    }
    {
      Attribute a = new CodeStringAttribute(TagFromName.Modality);
      a.addValue(modality);
      list.put(a);
    }

    {
      Attribute a = new SequenceAttribute(TagFromName.AcquisitionContextSequence);
      list.put(a);
    }
  }
    protected void doSomethingWithDicomFileOnMedia(String mediaFileName) {
      // logLn("OurFirstPassMediaImporter.doSomethingWithDicomFile(): "+mediaFileName);
      try {
        DicomInputStream i = new DicomInputStream(new File(mediaFileName));
        AttributeList list = new AttributeList();
        list.read(i);
        i.close();

        String sopInstanceUID =
            Attribute.getSingleStringValueOrEmptyString(list, TagFromName.SOPInstanceUID);
        if (sopInstanceUID.length() > 0) {
          Group group = mapOfSOPInstanceUIDToGroup.get(sopInstanceUID);

          // System.err.println("group = "+group);
          // System.err.println("Groups size = "+groups.size());
          if (group == null) {
            if (groups.size() == 1) {
              group = groups.toArray(singleGroupArray)[0];
            } else {
              throw new DicomException(
                  "Cannot merge context for second set if more than one group");
            }
          }

          if (group != null) {
            logLn("In group " + group.identity);
            if (group.context != null) {
              CompositeInstanceContext.removePatient(
                  list); // remove anything hanging around, such as empty attributes
              list.putAll(
                  group.context
                      .getAttributeList()); // overwrite all patient context in list that was read
                                            // in
            } else {
              throw new DicomException(
                  "Missing group context for SOPInstanceUID on second pass"); // should not be
                                                                              // possible
            }

            ClinicalTrialsAttributes.addContributingEquipmentSequence(
                list,
                true,
                new CodedSequenceItem("109103", "DCM", "Modifying Equipment"),
                "PixelMed", // Manufacturer
                "PixelMed", // Institution Name
                "Software Development", // Institutional Department Name
                "Bangor, PA", // Institution Address
                null, // Station Name
                "com.pixelmed.apps.MergeCompositeContext", // Manufacturer's Model Name
                null, // Device Serial Number
                "Vers. " + VersionAndConstants.getBuildDate(), // Software Version(s)
                "Merged patient context");

            list.removeGroupLengthAttributes();
            list.removeMetaInformationHeaderAttributes();
            list.remove(TagFromName.DataSetTrailingPadding);
            FileMetaInformation.addFileMetaInformation(
                list, TransferSyntax.ExplicitVRLittleEndian, ourAETitle);

            File dstFile =
                new File(
                    dstFolderName,
                    MoveDicomFilesIntoHierarchy.makeHierarchicalPathFromAttributes(list));
            if (dstFile.exists()) {
              throw new DicomException(
                  "\""
                      + mediaFileName
                      + "\": new file \""
                      + dstFile
                      + "\" already exists - not overwriting");
            } else {
              File dstParentDirectory = dstFile.getParentFile();
              if (!dstParentDirectory.exists()) {
                if (!dstParentDirectory.mkdirs()) {
                  throw new DicomException(
                      "\""
                          + mediaFileName
                          + "\": parent directory creation failed for \""
                          + dstFile
                          + "\"");
                }
              }
              logLn("Writing with new context file " + dstFile);
              list.write(dstFile, TransferSyntax.ExplicitVRLittleEndian, true, true);
            }
          } else {
            throw new DicomException(
                "Missing group for SOPInstanceUID on second pass"); // should not be possible for
                                                                    // single set case
          }
        } else {
          throw new DicomException("Missing SOPInstanceUID");
        }
      } catch (Exception e) {
        logLn("Error: File " + mediaFileName + " exception " + e);
      }
    }