vertex_desc_t add_neuron(const std::string& label,
					const typename pf_t::params_t& pf_params,
					const typename af_t::params_t& af_params) {
				vertex_desc_t v = add_neuron(label);
				_g[v].set_pfparams(pf_params);
				_g[v].set_afparams(af_params);
				return v;
			}
Neuron* Spiking_NNet::add_neuron(std::string name, double thresh, double decay){
    Neuron *rv = add_neuron(thresh, decay);
    std::pair<std::string, Neuron*> insert_me;
    std::pair<Neuron*, std::string> insert_me_inverse;
    insert_me = std::make_pair(name, rv);
    insert_me_inverse = std::make_pair(rv, name);
    named_neurons.insert(insert_me);
    neurons_to_name.insert(insert_me_inverse);
    return rv;
}
Spiking_NNet::Spiking_NNet(std::string json_text){

    using json = nlohmann::json;
    double rnd_buffer;
    std::vector<json> connections;
    std::string to_str;
    std::string name;
    double decay, threshold, weight;
    int to_int, speed;
    Neuron *out_n, *in_n;

    /* initialize random seed: */

    json net_data = json::parse(json_text);
    json json_neurons = net_data["neurons"];

    //Create a neuron for each representation
    for( auto it = json_neurons.begin(); it != json_neurons.end(); it++ ){
        //Handle decay
        if( (*it)["decay"].is_string() ){
            //Special assignment
            if( (*it)["decay"].get<std::string>() == "random" ){
                rnd_buffer = rand()/double(RAND_MAX);
                decay = rnd_buffer;
            }
        }
        else{
            //Assume it is a value
            decay = (*it)["decay"].get<double>();
        }

        //Handle threshold
        if( (*it)["threshold"].is_string() ){
            //Special assignment
            if( (*it)["threshold"].get<std::string>() == "random" ){
                rnd_buffer = rand()/double(RAND_MAX);
                threshold = rnd_buffer;
            }
        }
        else{
            //Assume it is a value
            threshold = (*it)["threshold"].get<double>();
        }


        //Check for name and add neuron
        if ( it->count("name") == 1){
            name = (*it)["name"].get<std::string>();
            add_neuron(name, threshold, decay);
        }
        else{
            add_neuron(threshold, decay);
        }
    }


    //Wire up connections
    int index = 0;
    for( auto it = json_neurons.begin(); it != json_neurons.end(); it++ ){

        //Because neurons were added to net in order, 
        //the index of a json_neuron and net neuron is the same
        //therefore..
        in_n = neurons[index];


        connections =  (*it)["connections"].get<std::vector<json> >();
        for ( auto con_it=connections.begin(); con_it != connections.end(); con_it++ ){
            if( (*con_it)["to"].is_string() ){
                std::string to_str = (*con_it)["to"].get<std::string>();
                out_n = get_neuron(to_str);


            }
            else{
                to_int = (*con_it)["to"].get<int>();
                //std::cout << "    connects to: " << to_int << std::endl;
                out_n = neurons.at(to_int);
            }
            
            //GET json weight;
            if( (*con_it)["weight"].is_string() ){
                weight = rand()/double(RAND_MAX);
            }
            else{
                //Assume its a double
                weight = (*con_it)["weight"];

            }


            //GET json speed
            if( (*con_it)["speed"].is_string() ){
                speed = rand()%3 + 1;
            }
            else{
                //Assume its a double
                speed = (*con_it)["speed"];
            }


            Neuron::connect(in_n, out_n, weight, speed);
        }
        index++;
    }


    //Check that neurons got created
    std::string output_identifier;
    for( int i=0; i<neurons.size(); i++ ){
        //printf("Neuron #: %d", i);
        if( neurons_to_name.count(neurons[i]) > 0 ){
           // printf(", name: %s\n", neurons_to_name.at(neurons[i]).c_str());
        }
        //printf("    threshold: %f\n", neurons[i]->get_threshold());
        //printf("    decay: %f\n", neurons[i]->get_decay());
        //printf("    num_of_outputs: %d\n", neurons[i]->get_outputs().size());

        //OUTPUTS
        std::vector<Neuron*> outputs = neurons[i]->get_outputs();
        //printf("    outputs:[\n");
        for ( int j=0; j<outputs.size(); j++ ){
            if( neurons_to_name.count(outputs[j]) > 0 ){
                output_identifier = neurons_to_name.at(outputs[j]);
            }else{
                //Get the index of neuron in vector neurons
                int pos = find(neurons.begin(), neurons.end(), outputs[j]) - neurons.begin();
                if(pos >= neurons.size()) {
                    //Out of bounds
                    output_identifier = "undefined";
                }else{
                    output_identifier = std::to_string(pos);
                }
            }
            //printf("        {\n");
            //printf("            'identifier':%s\n", output_identifier.c_str());

            //Get the weight and speed
           // printf("            'weight': %f\n", outputs[j]->weight_for(neurons[i]));
            //printf("            'speed': %d\n", outputs[j]->speed_for(neurons[i]));
            //printf("        }\n");
        }
        //printf("    ]\n");
        //printf("\n\n");
    }

}