// joycub V2 - an interpeter for the programming language Joy
// (c) 2004-2006 Sergey Zubkov 
// op.cc - prototype module to test out the new design considerations
static char RCSID[] ="$Id: list.cc,v 1.1 2006/02/27 18:50:34 cubbi Exp cubbi $";

#include <iostream>
#include <sstream>
#include "list.h"

// global object counters (for memory debugging)
int list_type_count = 0;

JC_list::JC_list(void) {
}

JC_list::JC_list(const vector<JC_objref*> & s) {
	for(vector<JC_objref*>::const_iterator it = s.begin();
					it!=s.end(); it++) {
		contents.push_back(*it);
	}
	list_type_count++;
};

JC_list::JC_list(const JC_list& j) {
//		cout << "list copy constr" << endl;
	list_type_count++;
	for(vector<JC_objref*>::const_iterator it = j.contents.begin();
					it!=j.contents.end(); it++) {
		contents.push_back( new JC_objref(**it) );
	}
};

JC_list::~JC_list(void) {
//		cout << "list destr" << endl;
	for(vector<JC_objref*>::const_iterator it = contents.begin();
				it!=contents.end(); it++) {
			delete *it;
	}
	contents.erase(contents.begin(), contents.end());
	list_type_count--;
};

const obj_type JC_list::get_type(void) const {
	return LIST;
};

std::string JC_list::to_string(void) const {
	std::ostringstream s;
	s << "[";
	for(vector<JC_objref*>::const_iterator it = contents.begin();
				it!=contents.end(); it++) {
			s << (*it)->to_string() << " ";
	}
	s << "]";
	return s.str();
}
std::string JC_list::to_output_string(void) const {
	std::ostringstream s;
	s << "[";
	for(unsigned int i=0; i<contents.size(); i++) {
		s << contents[i]->to_output_string();
	   	if(i<contents.size()-1) s << " ";
	}
	s << "]";
	return s.str();
}

void JC_list::debug_print(void) const {
	std::cout << to_string();
};

std::string JC_list::key(void) const { 
	return to_string();
};

vector<JC_objref*> & JC_list::get_contents(void) {
	return contents;
}

int JC_list::size(void) const {
	return contents.size();
}

JC_objref*& JC_list::operator[](int i) {
	return contents[i];
}

void JC_list::push_back(JC_objref* j) {
		contents.push_back(j);
}
void JC_list::push_front(JC_objref* j) {
	if(contents.size() == 0) {
		contents.push_back(j);
	} else {
		contents.push_back(contents.back()); // grow one element
		for(int i=contents.size()-1; i>0; i--) {
			contents[i]=contents[i-1];
		}
		contents[0]=j;
	}
}
// erase i'th element and move the rest up
void JC_list::drop(unsigned int i) {
	if(i >= contents.size()) return;
	delete contents[i];
	for(unsigned int j=i;  j<contents.size()-1; j++) {
		contents[j]=contents[j+1];
	}
	contents.pop_back(); // shrink one element
}
void JC_list::concat(JC_list & v2) {
    for(int i=0; i<v2.size(); i++)
        contents.push_back(new JC_objref(*v2[i]));
}

void JC_list::erase(void) {
	contents.erase(contents.begin(), contents.end());
}
