#include "export.h"
#include <algorithm>
#include <string>

// -----------------------------------------------------------------------
Export::Export(MStr filename)
{
    try {
        PLA_file.open((filename).c_str());
//         PLA_file.open((filename+".pla").c_str());
//         PLA_file_min.open((filename+"_min.pla").c_str());
    }
    catch(...){
        cout << "cannot open output file" << endl;
    }
}

// -----------------------------------------------------------------------
Export::~Export()
{
    PLA_file.close();
//     PLA_file_min.close();
}

// -----------------------------------------------------------------------
bool Export::export_to_pla(ofstream & file, list<PLA_elem *>& pla_list, int inputs, int outputs)
{
//     clock_t t_start, t_end;

//     cout << "jedeme" << endl;

    for(list<PLA_elem *>::iterator it = pla_list.begin(); it != pla_list.end(); it++){
        for(int i = 0;i < inputs;i++){
            if ((*it)->pla_inputs[i] == '2')
                file << "-";
            else
                file << (*it)->pla_inputs[i];
        }
        file << " ";
        for(int i = 0;i < outputs;i++){
            file << (*it)->pla_outputs[i];
        }
        
        file << endl;
    }

    return true;
}

// -----------------------------------------------------------------------
bool Export::export_to_pla(ofstream & file, char *in, char *out, int inputs, int outputs)
{
    for(int i = 0;i < inputs;i++){
        if (in[i] == '2')
            file << "-";
        else
            file << in[i];
    }

    file << " ";

    for(int i = 0;i < outputs;i++){
        file << out[i];
    }

    file << endl;

    return true;
}

// // -----------------------------------------------------------------------
// void Export::print_output(int inputs, int outputs)
// {
//     for(list<PLA_elem>::iterator it = pla_list.begin(); it != pla_list.end(); it++){
//         for(int i = 0;i < inputs;i++){
//             cout << it->pla_inputs[i] << " ";
//         }
//         cout << " ";
//         for(int i = 0;i < outputs;i++){
//             cout << it->pla_outputs[i];
//         }
//         cout << endl;
//     }
// }

// // -----------------------------------------------------------------------
// void Export::PLA_print_recursive(DdManager * dd, list<Bdd_elem> bdd_list, DdNode * node, int * _list)
// {
//     DdNode *N, *Nv, *Nnv;
//     int v, i, index;
//
//     N = Cudd_Regular(node);
//
//     if (cuddIsConstant(N)) {
// //      cout << "list " << N->index << endl;
//
//         if (node != background && node != zero) {
//             PLA_elem pla;
//             int *pla_outputs = new int[bdd_list.size()];
//             for (i = 0; i < dd->size; i++) {
//                 cout << _list[i] << " ";
//                 v = _list[i];
//                 if (v == 0)
//                     PLA_file << "0";
//                 else
//                     if (v == 1)
//                         PLA_file << "1";
//                     else
//                 PLA_file << "-";
//             }
// //             PLA_file << " ";
//             cout << endl;
//
//             for(list<Bdd_elem>::iterator it = bdd_list.begin(); it != bdd_list.end(); it++){
//                 i = 0;
//
// //                 cout << it->node->index << ":" << node->index << endl;
//                 if (it->type == T_OUTPUT){
//                     if (it->gate == out_var){
// //                         cout << "mam spravny vystup " << it->gate << endl;
// //                         PLA_file << cuddV(node);
//                         pla_outputs[i] = (int)cuddV(node);
//                     }
//                     else {
// //                         PLA_file << "0";
//                         pla_outputs[i] = 0;
//                     }
//                 }
//             }
//             pla.pla_outputs = pla_outputs;
//             pla.pla_inputs = _list;
//             pla_list.push_back(pla);
//             print_output(dd->size, 4);
// //             cout << "- 1" << endl;
// //             PLA_file << endl;
//         }
// //         else
// //             cout << "- 0" << endl;
//     }
//     else {
//         Nv  = cuddT(N);
//         Nnv = cuddE(N);
//         if (Cudd_IsComplement(node)) {
//             Nv  = Cudd_Not(Nv);
//             Nnv = Cudd_Not(Nnv);
//         }
//         index = N->index;
// //      cout << "uzel " << N->index << endl;
//         _list[index] = 0;
// //         cout << N->index << " E ";
//         PLA_print_recursive(dd,bdd_list,Nnv,_list);
// //         cout << N->index << " T ";
//         _list[index] = 1;
//         PLA_print_recursive(dd,bdd_list,Nv,_list);
//         _list[index] = 2;
//     }
//     return;
// }
//
// // -----------------------------------------------------------------------
// int Export::PLA_print(DdManager * manager, list<Bdd_elem> bdd_list, DdNode * node)
// {
//     int i, *list_;
//
//     background = manager->background;
//     zero = Cudd_Not(manager->one);
//     list_ = ALLOC(int,manager->size);
//
//     if (list_ == NULL) {
//         manager->errorCode = CUDD_MEMORY_OUT;
//         return(0);
//     }
//     for (i = 0; i < manager->size; i++)
//         list_[i] = 2;
//
//     PLA_print_recursive(manager, bdd_list, node, list_);
//     FREE(list_);
//
//     return 1;
// }
//
// -----------------------------------------------------------------------
void Export::PLA_print_header(ofstream & file, list<Bdd_elem>& bdd_list, int inputs, int outputs)
{
    file << ".i " << inputs << endl;
    file << ".o " << outputs << endl;
    file << ".ilb ";

    list<Bdd_elem>::iterator iter = bdd_list.begin();
    if (iter->type == T_INPUT)
        file << iter->gate;
    iter++;
// 
    while(iter->type == T_INPUT){
        file << " " << iter->gate;
        iter++;
    }

    file << endl;

    file << ".ob ";

    while(iter != bdd_list.end()){
        if (iter->type == T_OUTPUT)
            file << iter->gate << " ";
        iter++;
    }

    file << endl;
    file << ".type fd" << endl;
}

// -----------------------------------------------------------------------
void Export::PLA_print_footer(ofstream & file)
{
    file << ".e" << endl;
}
