/******************************************************************************
    Copyright (c) 1998-2000 CoWare, Inc.    ALL RIGHTS RESERVED

The following code is derived, directly or indirectly, from the SystemC
source code released by Synopsys, Inc Copyright (c) 1996-2001, Synopsys,
Inc., CoWare, Inc., Frontier Design, Inc. and others. All Rights reserved.
The contents of this file are subject to the restrictions and limitations
set forth in the SystemC Open Source License Version 2.0 (the "License");
You may not use this file except in compliance with such restrictions and
limitations. You may obtain instructions on how to receive a copy of the
License at http://www.systemc.org/.  Software distributed by Contributors
under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
ANY KIND, either express or implied. See the License for the specific
language governing rights and limitations under the License."

******************************************************************************/

/****************************************************************

    Authors : Harish Sarin, CoWare Inc. (harish@coware.com)
	    : Cesar Quiroz, CoWare Inc. (cesar@coware.com)
            : Vijay Kumar,  CoWare Inc. (vijay@coware.com)
            : Dirk Vermeersch,  CoWare Inc. (dirk@coware.com)

    MODIFICATION LOG
    Modifier Name & Affiliation:
    Description of Modification:

****************************************************************/
#ifndef SC_TIME_H
#define SC_TIME_H
#include "numeric_bit/sc_nbdefs.h"

enum sc_time_unit { sc_fs=0,sc_ps=1,sc_ns=2,sc_us=3,sc_ms=4,sc_sec=5 };

class sc_time {
  uint64 value;
  static uint64 time_resolution;
public:
  // operator uint64() const {return value;}
     // removed because value scaled wrong
  sc_time(double v,sc_time_unit t);
  sc_time(int v, sc_time_unit t);
  explicit sc_time(double v,bool scale = true);
  explicit sc_time(uint64 v,bool scale = true);
  explicit sc_time(int v,bool scale = true);
  sc_time():value(0){}

  uint64 getValue() const {
    return value;
  }

  void setValue(uint64 v) {
    value = v;
  }

  bool operator >(const sc_time &t) const {
    return value > t.value;
  }

  bool operator <(const sc_time &t) const {
    return value < t.value;
  }

  bool operator <=(const sc_time &t) const {
    return value <= t.value;
  }

  bool operator >=(const sc_time &t) const {
    return value >= t.value;
  }

  bool operator ==(const sc_time &t) const {
    return value == t.value;
  }

  bool operator !=(const sc_time &t) const {
    return value != t.value;
  }

  sc_time& operator +=(const sc_time& t){
     value += t.getValue();
     return *this;
  }

  sc_time& operator -=(const sc_time& t){
     value -= t.getValue();
     return *this;
  }

  sc_time& operator *=(double d) {
//<SystemC_Win>
//#if defined(_MSC_VER)
#if defined(WIN32)
//</SystemC_Win>
     value = uint64((int64)value * d);
#else
     value = uint64(value * d);
#endif
     return *this;
  }

  sc_time& operator /=(double d) {
//<SystemC_Win>
//#if defined(_MSC_VER)
#if defined(WIN32)
//</SystemC_Win>
     value = uint64((int64)value / d);
#else
     value = uint64(value / d);
#endif
     return *this;
  }


  friend sc_time operator*(double, const sc_time&);
  friend sc_time operator*(const sc_time&, double);
  friend sc_time operator/(const sc_time&, double);
  friend double operator/(const sc_time&, const sc_time&);
  friend void sc_set_time_resolution(int v, sc_time_unit t);
  friend void sc_set_time_resolution(sc_time &);
  friend sc_time sc_get_time_resolution();
  friend ostream& operator<<(ostream&, const sc_time&);
  friend uint64 sc_get_uint64(sc_time&);
};

inline
sc_time  operator +(const sc_time &t1,const sc_time &t2) {
  return sc_time(t1) +=  t2;
}

inline
sc_time  operator -(const sc_time &t1,const sc_time &t2) {
  return sc_time(t1) -= t2;
}


extern
sc_time sc_get_time_resolution();

extern
void  sc_set_time_resolution(int v, sc_time_unit t);

extern
void  sc_set_time_resolution(sc_time &);

extern
void sc_print_time_resolution();

extern
sc_time sc_get_default_time_unit();

extern void
sc_set_default_time_unit(sc_time &);

extern double sc_time_to_double(const sc_time &);


#endif
