/* Rock.h provides the declaration of class Rock.
 *
 * Class Invariant:
 *    The value of myRockName is one of the following:
 *       BASALT, DOLOMITE, GRANITE, LIMESTONE, MARBLE, 
 *       OBSIDIAN, QUARTZITE, SANDSTONE, SHALE, SLATE
 ***************************************************************/

#ifndef ROCK
#define ROCK

#include <iostream>                                // istream, ostream
using namespace std;
#include "RockKind.h"                          // class RockKind
// #include "RockTexture.h"                             // class RockTexture

enum RockName {ROCK_UNDERFLOW = -1,
               BASALT, DOLOMITE, GRANITE,           // recognized
               LIMESTONE, MARBLE, OBSIDIAN,         //  names of
               QUARTZITE, SANDSTONE, SHALE, SLATE,  //  rocks
               NUMBER_OF_ROCKS,
               ROCK_OVERFLOW = NUMBER_OF_ROCKS};

class Rock
{
 public:                                             // constructors:
   Rock();                                           //  default value
   Rock(RockName initialRock);                       //  explicit value

   void read(istream & in);                          // input
   void print(ostream & out) const;                  // output

   RockKind kind() const;                            // igneous, ...
//   RockTexture texture() const;                      // coarse, ...

   Rock operator++();                                // prefix ++
   Rock operator++(int);                             // postfix ++
   Rock operator--();                                // prefix --
   Rock operator--(int);                             // postfix --

                                                     // relationals
   friend bool operator==(const Rock & left, const Rock & right);  
   friend bool operator!=(const Rock & left, const Rock & right);  
   friend bool operator<(const Rock & left, const Rock & right);  
   friend bool operator>(const Rock & left, const Rock & right);  
   friend bool operator<=(const Rock & left, const Rock & right);  
   friend bool operator>=(const Rock & left, const Rock & right);  

 private:
   RockName myRockName;
};

// -------- Function input -------------------------------------
inline istream& operator>>(istream& in, Rock& theRock)
{
   theRock.read(in);
   return in;
}

// -------- Function output ------------------------------------
inline ostream& operator<<(ostream& out, const Rock& theRock)
{
   theRock.print(out);
   return out;
}

// -------- Initialize me (default value) -------------------------
inline Rock::Rock()
{
   myRockName = BASALT;
}

// -------- Initialize me (explicit-value) ------------------------
#include <cassert>
using namespace std;
inline Rock::Rock(RockName initialRock)
{
   assert(BASALT <= initialRock && initialRock < NUMBER_OF_ROCKS);
   myRockName = initialRock;
}

//--------- Compare me and anotherRock using == -------------
inline bool operator==(const Rock& left, const Rock& right)
{
   return left.myRockName == right.myRockName;
}

//--------- Compare me and anotherRock using != -------------
inline bool operator!=(const Rock& left, const Rock& right)
{
   return left.myRockName != right.myRockName;
}

//--------- Compare me and anotherRock using < -------------
inline bool operator<(const Rock& left, const Rock& right)
{
   return left.myRockName < right.myRockName;
}

//--------- Compare me and anotherRock using > -------------
inline bool operator>(const Rock& left, const Rock& right)
{
   return left.myRockName > right.myRockName;
}

//--------- Compare me and anotherRock using <= -------------
inline bool operator<=(const Rock& left, const Rock& right)
{
   return left.myRockName <= right.myRockName;
}

//--------- Compare me and anotherRock using >= -------------
inline bool operator>=(const Rock& left, const Rock& right)
{
   return left.myRockName >= right.myRockName;
}


#endif

