/** \file dottypesystemwriter.cpp .
-----------------------------------------------------------------------------


 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.

-----------------------------------------------------------------------------

   Description:

-----------------------------------------------------------------------------


   09/20/2002  Initial creation

-------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"
#include "uima/dottypesystemwriter.hpp"
#include "uima/timedatetools.hpp"
#include "unicode/ustring.h"
#include "uima/unistrref.hpp"
#include "uima/typesystem.hpp"
#include "uima/cas.hpp"
#include <time.h>
#ifdef _MSC_VER
#include <minmax.h> // for min
#endif

/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */

using namespace std;

namespace uima {

  const size_t cuiINDENT = 3;

  std::string
  currDateString() {
    time_t ltime;
    (void)time(&ltime);   //get time, ignore return value
    const size_t uiMAXSTR = 64;
    char pszDate[uiMAXSTR];
    strftime(pszDate, uiMAXSTR, "%x", localtime(&ltime));
    string t(pszDate);
    return t; //time string
  }

  UnicodeStringRef adjustTypeName(UnicodeStringRef ulstrName) {
    UnicodeString ustrTypePfx( "uima" );                         // Our namespace
    ustrTypePfx.append( (UChar) uima::TypeSystem::NAMESPACE_SEPARATOR );
    if (u_strncmp(ulstrName.getBuffer(), ustrTypePfx.getBuffer(), min(ulstrName.length(), ustrTypePfx.length())) == 0) {
      ulstrName = UnicodeStringRef(ulstrName.getBuffer() + ustrTypePfx.length(),
                                   ulstrName.length()- ustrTypePfx.length());
    }
    return ulstrName;
  }

  UnicodeStringRef adjustFeatName(UnicodeStringRef ulstrName) {
    return ulstrName;
  }

  DotTypeSystemWriter::DotTypeSystemWriter(CAS const & crCAS, bool bNoCASTypes, bool bOnlyCASTypes ) :
      iv_crCAS(crCAS),
      iv_bNoCASTypes(bNoCASTypes),
      iv_bOnlyCASTypes(bOnlyCASTypes) {}

  static inline bool isCasType(uima::Type const & crType) {
    return    crType.getName().startsWith(icu::UnicodeString("uima.cas." ))
              || crType.getName().startsWith(icu::UnicodeString("uima.tcas."));
  }

  void DotTypeSystemWriter::writeType(ostream & os, uima::Type const & crType, size_t uiIndent) const {
    if (iv_bOnlyCASTypes &&
        (crType != crType.getTypeSystem().getTopType()) && (!isCasType(crType))) {
      return;
    }
    if (iv_bNoCASTypes && isCasType(crType)) {
      return;
    }
    string strIndentString(uiIndent, ' ');
    os << strIndentString;
    os << adjustTypeName(crType.getName())
    << "[label=\"" << adjustTypeName(crType.getName());
    vector<Feature> features;
    crType.getAppropriateFeatures(features);
    size_t i;
    for (i=0; i<features.size(); ++i) {
      assert( features[i].isValid());
      // print only features which are introduced at this type
      Type introType;
      features[i].getIntroType(introType);
      assert( introType.isValid() );
      if (introType == crType) {
        Type range;
        features[i].getRangeType(range);
        assert( range.isValid());
        os << "|{" << adjustFeatName(features[i].getName()) << ": " << adjustTypeName(range.getName()) << "}";
      }
    }
    os << "\"];" << endl;
    vector<Type> subTypes;
    crType.getDirectSubTypes(subTypes);
    if (subTypes.size() > 0) {
      // print <typename> -> {<sub-type1>, <sub-type2>, ...};
      os << strIndentString;
      os << adjustTypeName(crType.getName()) << " -> {";
      size_t uiTypesWritten = 0;
      for (i=0; i<subTypes.size(); ++i) {
        if (iv_bOnlyCASTypes && !isCasType(subTypes[i]) ) {
          continue;
        }
        if (iv_bNoCASTypes && isCasType(subTypes[i]) ) {
          continue;
        }
        if (uiTypesWritten > 0 ) {
          os << "; ";
        }
        os << adjustTypeName(subTypes[i].getName());
        ++uiTypesWritten;
      }
      os << "};" << endl;
    }
    for (i=0; i<subTypes.size(); ++i) {
      writeType(os, subTypes[i], uiIndent+cuiINDENT);
    }
  }

  void DotTypeSystemWriter::write(std::ostream & os) const {
    os << "digraph G {\n"
    "   graph [rankdir=LR];\n"
    "   label=\"     Type\\n     Hierarchy\\n     " <<
    currDateString() << "\";\n";
    os << "   fontsize=24;\n"
    "   fontname=Helvetica;\n"
    "   color=white;\n"
    "   node [shape=Mrecord, /*style=bold, */ fontsize=10, width=2.4, height=.28];\n";
    Type top = iv_crCAS.getTypeSystem().getTopType();
    writeType(os, top, cuiINDENT);
    os << "}" << endl;
  }

} // namespace uima

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */



