// complex_struct_unreadable.c - complex structs may be unreadable
//                               if used naively

#include <stdio.h>
#include <stdlib.h>

// an office number in our institute consists of the letter that
// stands for the single building, a floor-number in this
// building and an office number on this floor. E.g.: D 1.15
struct OfficeNumber
{
  char building;       // the single letter for the building
  short floor;         // the floor number
  short office_number; // the office number on the floor
};

// a typical address
struct Address
{
  char *country;   // the country, e.g. Austria
  char *state;     // the state in the country if applicable
                   // e.g. Minnesota for addresses in the USA
                   // NULL if not applicable
  char *zip_code;  // the zip code, e.g. A-8010
  char *city;      // the city, e.g. Graz
  char *street;    // the streetname
  char *number;    // the number of the building in the 
                   // street. This is a string, because there
                   // can also be numbers containing letters!
};

// an office is exactly defined 
struct Office
{
  struct Address building_address; // address of the building
  struct OfficeNumber office_num;  // the office in the building
};

// constant for extension in struct PhoneNumber below

#define NO_EXTENSION -1L

// a telephone number
struct PhoneNumber
{
  unsigned short country_prefix; // the prefix for the country, 
                                 // e.g. 43 for Austria
  unsigned short region_prefix;  // the prefix for the region,
                                 // e.g. 316 for Graz
  unsigned long phone_number;    // the actual phone number. Please
                                 // note that we assume here that
                                 // a long has to be long enough to
                                 // store a number. For demo only!
  long extension;                // the extension, if applicable
                                 // please note that we take a 
                                 // signed type here, because
                                 // a neg. number signals us that
                                 // there is "no extension".
};

// employees in a company
struct Employee
{
  char *first_names;        // the first name(s) of the employee
  char *second_name;        // the name of the employee
  struct Office office;     // the office of the employee
  struct PhoneNumber phone; // the phone number of the employee
  struct PhoneNumber fax;   // the fax number of the employee
  char *email;              // the email address of the employee
                            // or NULL if not available
};

//------------------------------------------------------------
int main()
{
  struct Employee test_employee;

  test_employee.first_names = "Otto";
  test_employee.second_name = "Muster";
  test_employee.office.building_address.country = "Austria";
  test_employee.office.building_address.state = NULL;
  test_employee.office.building_address.zip_code = "A-8010";
  test_employee.office.building_address.city = "Graz";
  test_employee.office.building_address.street = "Inffeldgasse";
  test_employee.office.building_address.number = "16c";
  test_employee.office.office_num.building = 'D';
  test_employee.office.office_num.floor = 1;
  test_employee.office.office_num.office_number = 15;
  test_employee.phone.country_prefix = 43;
  test_employee.phone.region_prefix = 316;
  test_employee.phone.phone_number = 87341;
  test_employee.phone.extension = 3208;
  test_employee.fax.country_prefix = 43;
  test_employee.fax.region_prefix = 316;
  test_employee.fax.phone_number = 873461;
  test_employee.fax.extension = NO_EXTENSION;
  test_employee.email = "otto@nowhere.nocom";

  printf("Employee: %s %s\n",test_employee.first_names,
                             test_employee.second_name);
  printf("Office:   %s %s\n          %s %s\n",
         test_employee.office.building_address.street,
         test_employee.office.building_address.number,
         test_employee.office.building_address.zip_code,
         test_employee.office.building_address.city);
  if (test_employee.office.building_address.state)
    printf("          %s, %s\n",
           test_employee.office.building_address.state,
           test_employee.office.building_address.country);
  else
    printf("          %s\n",
           test_employee.office.building_address.country);
  printf("          Room: %c %d %d\n",
                    test_employee.office.office_num.building,
                    test_employee.office.office_num.floor,
                    test_employee.office.office_num.office_number);
  printf("Phone:    +%d-%d-%d",
                    test_employee.phone.country_prefix,
                    test_employee.phone.region_prefix,
                    test_employee.phone.phone_number);
  if (test_employee.phone.extension != NO_EXTENSION)
    printf("-%d\n",test_employee.phone.extension);
  else
    printf("\n");
  printf("Fax:      +%d-%d-%d",
                    test_employee.fax.country_prefix,
                    test_employee.fax.region_prefix,
                    test_employee.fax.phone_number);
  if (test_employee.fax.extension != NO_EXTENSION)
    printf("-%d\n",test_employee.fax.extension);
  else
    printf("\n");
  printf("Email:    %s\n",test_employee.email);
}

