// Lexicon EntryList index routines
//
// Copyright 2001, KUN.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

// $Id: lexentrylistidx.cc,v 1.9 2005/04/14 12:46:41 olafs Exp $

using namespace std;
#include <stdlib.h>
#include <iostream>
#include "lexfileio.h"
#include "lexentrylistidx.h"

LexEntryListIdx::LexEntryListIdx() {
    next_free_idx = 0;
}

void
LexEntryListIdx::dump(void) const
{
    unsigned ptr = 0;

    cout << "---- LexEntryListIdx::dump" << endl;
    for (unsigned i = 0; i < list_index.size(); ++i) {
        LexEntryList_t::const_iterator iter = list_index[i];
        EntryList entlst = iter->second.first;
        ptr = iter->second.second;
        
        for (unsigned j = 0; j < iter->second.first.size(); ++j) {
            cout << "\t" << ptr << ": ";
            cout << "(" << lex_entry_list.get_index(entlst[j]);
            cout << ", ";

            if (j + 1 == entlst.size()) {
                cout << "-1)";
            } else {
                cout << ptr + 1 << ")";
            }

//            cout << "\t" << (list[i].first)[j];
            cout << endl;

            ptr++;
        }
    }
    cout << "----" << endl;
}

void
LexEntryListIdx::write_output(ostream& os) const
{
    lex_entry_list.write_output(os); // write member (used to be global)

    write_lex_size_and_log(os, size(), " entry list indexes to file");

    unsigned ptr = 0;
    unsigned lisiz = list_index.size();

    for (unsigned ii = 0; ii < lisiz; ++ii) {
        LexEntryList_t::const_iterator iter = list_index[ii];
        EntryList entlst = iter->second.first;
        unsigned elsiz = entlst.size();

        for (unsigned jj = 0; jj < elsiz; ++jj) {
            ptr++;
            unsigned wx = lex_entry_list.get_index(entlst[jj]);
            write_lex_index(os, wx);	// reading.c:entrylist_pair->index

            // FN: writing pointer as unsigned keeps the output identical
            //	to the inefficiently written version
            if (jj + 1 == elsiz) {
                wx = (unsigned) -1;
            } else {
                wx = ptr;
            }
            write_lex_index(os, wx);	// reading.c:entrylist_pair->pointer
        }
    }
}

pair<unsigned,int>
LexEntryListIdx::get_idx_and_ptr_by_index(unsigned idx) {
    if (idx >= next_free_idx) {
        cout << "Internal error in LexEntryListIdx::get_idx_and_ptr_by_index: unknown index " << idx << endl;
        exit(1);
    }

    unsigned ptr = 0;

    for (unsigned i = 0; i < list_index.size(); ++i) {
        LexEntryList_t::iterator iter = list_index[i];

        for (unsigned j = 0; j < iter->second.first.size(); ++j) {
            if (ptr == idx) {
                unsigned a = lex_entry_list.get_index((iter->second.first)[j]);
                int b;

                if (j + 1 == iter->second.first.size()) {
                    b = -1;
                } else {
                    b = ptr + 1;
                }
                return pair<unsigned,int>(a,b);
            }

            ptr++;
        }
    }

    // This can't happen
    cout << "Internal error in LexEntryListIdx::get_idx_and_ptr_by_index: index " << idx << " not found" << endl;
    exit(1);
    return pair<unsigned,int>(0,0);	// get rid of warning
}
