Version:0.9 StartHTML:0000000105 EndHTML:0000023099 StartFragment:0000000152 EndFragment:0000023065
/******************************************************/
/*************** Isidro Pastor Jorda ******************/
/*************** Noemi Ruth Moya Hinojo ***************/
/******************************************************/
/****************** Telematica ************************/
/******************** FPII ****************************/
/****************** Practica 4 ************************/
/******************************************************/

#include <iostream.h>
#include <stdlib.h>
#include <fstream.h>
#include "ColaE.h"

const int ORDENADORES = 5;   // Numero de ordenadores que tenemos en nuestra red local

typedef Cola Vec[ORDENADORES];

bool CargarColas(Vec v);
bool RepartirColas(Vec v, Cola & bw, Cola & color);
bool Imprimir(Cola & bw, Cola & color);
bool GrabarHistorico (string fich, Dato aux );
void VerColas(Cola bw,Cola color);


int main()
{

    Vec v;   // Vector donde almacenamos las Colas de los ordenadores de nuestra red local
    Cola bw, color; // Colas de las impresoras

    if (CargarColas(v))
    {
        RepartirColas(v, bw, color);
        Imprimir (bw, color);
    }

    else
        cerr << " Error cargando el fichero prueba.txt " << endl;


    system("PAUSE");
    return 0;
}


/*****************************************************************************
* Funcion: CargarColas
* Descripcion: Cargamos del archivo prueba.txt las Colas de impresion de los PC's
*
*
*
* Parametros:
*
* Nombre        E/S       Descripcion
* ------       -----      -----------
*   v           E/S       Vector donde almacenamos todas las colas de los ordenadores
*
*
*
* Valor devuelto:
*       True si no han habido errores cargando las colas, false en caso contrario.
*****************************************************************************/

bool CargarColas(Vec v)
{
    ifstream f;
    Dato datos;
    string aux;
    bool ok = true;

    f.open("prueba.txt");

    if (!f)
    {
        cerr << " Error leyendo el fichero" << endl;
        ok = false;
    }
    else
    {
        getline (f, aux); // Cargamos la primera linea de texto del fichero prueba.txt

        while ( !f.eof() )
        {
            datos.pc = int ( aux[0] - '0' );  // Con esto obtenemos el entero que corresponde al pc que imprime

            aux.erase(0,2);                   // Borramos el primer caracter de indicativo del pc y el espacio blanco

            if (aux.find("bw") != -1)         // Buscamos si la impresora es la bw
            {
                datos.impresora = "bw";       // Si es la bw entonces asignamos el valor bw a impresora
                aux.erase( aux.find("bw")-1, 3); // Borramos en el string el espacio blanco anterior al nombre de la impresora y la impresora
            }
            else
            {
                datos.impresora = "color";    // Si no es bw sera de color, asignamos color al campo impresora
                aux.erase ( aux.find("color")-1,6); // y borramos el espacio en blanco anterior y el nombre de la impresora
            }

         /****************************************************************
         * Como ya hemos eliminado del string las partes que corresponden*
         * al numero de pc que imprime y la impresora que usa, solamente *
         * nos queda en el string el nombre del documento que vamos a    *
         * imprimir, independientemente de la longitud del nombre del    *
         * fichero y de la longitud de su extension, permitiendo nombres *
         * de mas de 8 caracteres y extensiones de mas de 3 caracteres   *
         * como miweb.html o computadores.pdf                            *
         *****************************************************************/

            datos.documento = aux;

            if ( !(v[(datos.pc)-1].Encolar(datos)))  // Encolamos los datos obtenidos, si no podemos hacerlo damos un mensaje de error
            {
                cerr << " La cola del ordenador " << datos.pc << " esta llena y no se ha podido ";
                cerr << "encolar el trabajo " << datos.documento << endl;
            }
            getline (f, aux); // cargamos la siguiente linea de texto del fichero de entrada

        }  // while

    } // else
    return (ok);
};


/*****************************************************************************
* Funcion: RepartirColas
* Descripcion: Repartimos las colas de cada ordenador a la cola de la
*              impresora correspondiente
*
*
*
* Parametros:
*
* Nombre        E/S       Descripcion
* ------       -----      -----------
*   v           E/S       Vector donde tenemos todas las colas de los ordenadores
*   bw          E/S       Cola de la impresora blanco y negro
* color         E/S       Cola de la impresora color
*
*
* Valor devuelto:
*       True si no han habido errores cargando las colas, false en caso contrario.
*****************************************************************************/

bool RepartirColas(Vec v, Cola & bw, Cola & color)
{
    int i;
    bool ok;
    Dato aux;

    ok = true;

    for (i = 0; i < ORDENADORES; i++) // Bucle para recorrer el vector de Colas de cada ordenador
    {
        while ( ! (v[i].ColaVacia()) )  // Mientras que la cola no este vacia
        {
            v[i].PrimeroCola(aux);      // Miramos el primer dato de la Cola
            if ( aux.impresora == "bw") // Si la impresora es la bw
            {
                if ( ! bw.Encolar(aux) )// Encolamos en la cola bw, si se producen errores mostramos el error por pantalla
                {
                    cerr << " Error, la cola bw esta llena y no se encolo el fichero "<< aux.documento << endl;
                    ok = false;
                } // if
            } // if
            else
            {
                if ( !color.Encolar(aux) ) // Si el trabajo no es para la impresora de bw imprimimos en la de color
                {
                    cerr << " Error, la cola color esta llena y no se encolo el fichero "<< aux.documento << endl;
                    ok = false;
                } // if
            } // else
            v[i].Desencolar();  // Al asignar a una de las dos Colas de impresoras desencolamos de la Cola del pc
        } // while             // Repetiremos esto hasta que tengamos la cola a repartir vacia
    } // for                  // Repetiremos el bucle hasta terminar con todas las colas de los ordenadores

    return (ok);
};

/*****************************************************************************
* Funcion: Imprimir
* Descripcion: Simulacion de la impresion de los trabajos que haya en cada Cola
*
*
*
* Parametros:
*
* Nombre        E/S       Descripcion
* ------       -----      -----------
*   bw          E/S       Cola de la impresora blanco y negro
* color         E/S       Cola de la impresora color
*
*
* Valor devuelto:
*       True si no han habido errores en la simulacion, false en caso contrario.
*****************************************************************************/


bool Imprimir(Cola & bw, Cola & color)
{
    int i, error;
    bool ok;
    Dato aux;

    ok = true;
    i = 1;

    VerColas( bw, color);  // Mostramos por pantalla las colas completas antes de imprimir

    while ( ! color.ColaVacia() )  // Mientras que la Cola color no este vacia
    {

        cout << "Paso " << i << endl;

        color.PrimeroCola(aux);

        error = 1 + rand() % 100;  // Generamos un valor que indicara el error cometido al imprimir en color

        if ( aux.documento.find (".doc") != -1 ) // Si encontramos la extension .doc en el documento a imprimir
        {
            if ( error <= 40)   // El error sera del 40%, si esta dentro de este margen de error mostraremos el error por pantalla
            {
                cerr << "Error imprimiendo " << aux.documento << endl;
                if ( ! bw.Encolar(aux) )  // En este caso debemos encolar en bw si podemos, si no podemos damos error
                {
                    cerr << " La cola bw esta llena, no se podra imprimir el fichero " << endl;
                    ok = false;
                }  // if
            } // if
            else   // Si no esta dentro del margen de error entonces imprimimos sin problemas y grabamos el historico
            {
                cout << " Imprimiendo " << aux.documento << " en impresora color " << endl;
                GrabarHistorico ( "color.txt", aux );
            }  // else
        } // if
        else    //  Si el documento no tiene extension .doc ....
        {
            if ( error <= 10)  // el error sera del 10% y si esta dentro del margen mostramos error por pantalla
            {
                cerr << " Error imprimiendo " << aux.documento << endl;
                if ( !bw.Encolar(aux) )  // En este caso debemos encolar en bw si podemos, si no podemos damos error
                {
                    cerr << " La cola bw esta llena, no se podra imprimir el fichero " << endl;
                    ok = false;
                } // if
            }
            else   // Si no esta dentro del margen de error entonces imprimimos sin problemas y grabamos el historico
            {
                cout << " Imprimiendo " << aux.documento << " en impresora color " << endl;
                GrabarHistorico ( "color.txt", aux );
            }  // else

        }// else

        color.Desencolar();  // En cualquier caso desencolaremos el trabajo de la cola color
        VerColas (bw, color); // y mostraremos el contenido de las dos colas despues de la impresion
        i++;                 // Aumentamos el indice de pasos
        if (i % 2 == 0)
        {
            cout << " Pulse la tecla intro para seguir con las impresiones\n";
            cin.get();
        }



    }// while

    while ( !bw.ColaVacia()) // ahora imprimiremos con la impresora de blanco y negro
    {
        bw.PrimeroCola(aux);
        cout << " Paso " << i << endl;
        cout << " Imprimiendo " << aux.documento << " en impresora bw " << endl;
        bw.Desencolar();
        VerColas(bw,color);
        GrabarHistorico("bw.txt",aux);
        i++;

        if (i % 2 == 0)
        {
            cout << " Pulse la tecla intro para seguir con las impresiones\n";
            cin.get();
        }

    }

    cout << " Se terminaron los trabajos de impresion " << endl;

    return (ok);
};

/*****************************************************************************
* Funcion: GrabarHistorico
* Descripcion: Graba el fichero historico de impresiones
*
*
*
* Parametros:
*
* Nombre        E/S       Descripcion
* ------       -----      -----------
*   fich        E         Nombre del fichero historico donde grabaremos
*   aux         E         Datos a grabar en el fichero historico
*
*
* Valor devuelto:
*       True si no han habido errores en la grabacion del fichero, false en caso contrario.
*****************************************************************************/

bool GrabarHistorico (string fich, Dato aux )
{
    ofstream f;
    bool ok;

    f.open(fich.c_str(), ios::app);  // Abrimos el fichero en modo "anyadir" para que grabe a continuacion de su contenido

    if (!f)  // Si no podemos abrir el fichero damos error
    {
        ok = false;
        cerr << " Error grabando en el fichero de historicos " << fich << endl;
    }
    else  // Si lo podemos abrir anyadimos al fichero los datos de la estructura aux
    {
        f << aux.pc << " " << aux.documento << " " << aux.impresora << endl;
        ok = true;
        f.close();
    }

    return (ok);
};

/*****************************************************************************
* Funcion: VerColas
* Descripcion: Muestra por pantalla el contenido de dos Colas
*
*
*
* Parametros:
*
* Nombre        E/S       Descripcion
* ------       -----      -----------
*   bw          E       Cola de la impresora blanco y negro
* color         E       Cola de la impresora color
*
*
* Valor devuelto:
*       True si no han habido errores mostrando las Colas, false en caso contrario.
*****************************************************************************/

void VerColas(Cola bw, Cola color)
{
    /************************************************************
    * Estas Colas estan pasadas por valor por lo que usaremos   *
    * el constructor de copia al pasar las dos colas a esta     *
    * funcion y operaremos sobre las copias de las Colas y no   *
    * directamente sobre las Colas de las impresoras originales *
    * que no resultaran modificadas despues de esta funcion.    *
    *************************************************************/



    Dato aux;

    cout << " Cola: Color " << endl;
    while ( !color.ColaVacia() ) // mientras que la Cola no sea vacia mostramos por pantalla el contenido de sus elementos
    {
        color.PrimeroCola(aux);
        cout << aux.pc << " " << aux.documento << " " << aux.impresora << endl;
        color.Desencolar();
    }
    cout << " Cola: bw" << endl;
    while ( !bw.ColaVacia() )
    {
        bw.PrimeroCola(aux);
        cout << aux.pc << " " << aux.documento << " " << aux.impresora << endl;
        bw.Desencolar();
    }
    cout << endl;
    return;
}