/* serialize a statement */
static int
raptor_turtle_serialize_statement(raptor_serializer* serializer, 
                                  const raptor_statement *statement)
{
  raptor_turtle_context* context=(raptor_turtle_context*)serializer->context;
  raptor_abbrev_subject* subject = NULL;
  raptor_abbrev_node* predicate = NULL;
  raptor_abbrev_node* object = NULL;
  int rv;
  raptor_identifier_type object_type;
  int subject_created = 0;
  int predicate_created = 0;
  int object_created = 0;

  if(!(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE ||
       statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS ||
       statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL)) {
    raptor_serializer_error(serializer,
                            "Do not know how to serialize node type %d\n",
                            statement->subject_type);
    return 1;
  }  

  subject = raptor_abbrev_subject_lookup(context->nodes, context->subjects,
                                         context->blanks,
                                         statement->subject_type,
                                         statement->subject,
                                         &subject_created);
  if(!subject) {
    return 1;
  }

  object_type=statement->object_type;
  if(object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL) {
    if(statement->object_literal_datatype &&
       raptor_uri_equals_v2(serializer->world, 
                            statement->object_literal_datatype, 
                            context->rdf_xml_literal_uri))
      object_type = RAPTOR_IDENTIFIER_TYPE_XML_LITERAL;
  }


  if(!(object_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE ||
       object_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS ||
       object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL ||
       object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL || 
       object_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL)) {
    raptor_serializer_error(serializer,
                            "Cannot serialize a triple with object node type %d\n",
                            object_type);
    return 1;
  }

  object = raptor_abbrev_node_lookup(context->nodes, object_type,
                                     statement->object,
                                     statement->object_literal_datatype,
                                     statement->object_literal_language,
                                     &object_created);
  if(!object)
    return 1;          


  if((statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_PREDICATE) ||
     (statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE)) {
    predicate = raptor_abbrev_node_lookup(context->nodes,
                                          statement->predicate_type,
                                          statement->predicate, NULL, NULL,
                                          &predicate_created);
    if(!predicate)
      return 1;
	      
    rv = raptor_abbrev_subject_add_property(subject, predicate, object);
    if(rv < 0) {
      raptor_serializer_error(serializer,
                              "Unable to add properties to subject %p\n",
                              subject);
      return rv;
    }
  
  } else if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) {
    int idx = *(int*)statement->predicate;
    rv = raptor_abbrev_subject_add_list_element(subject, idx, object);
    if(rv) {
      /* An ordinal might already exist at that location, the fallback
       * is to just put in the properties list */
      predicate = raptor_abbrev_node_lookup(context->nodes,
                                            statement->predicate_type,
                                            statement->predicate, NULL, NULL,
                                            &predicate_created);
      if(!predicate)
        return 1;

      rv = raptor_abbrev_subject_add_property(subject, predicate, object);
      if(rv < 0) {
        raptor_serializer_error(serializer,
                                "Unable to add properties to subject %p\n",
                                subject);
        return rv;
      }
    }
  } else {
    raptor_serializer_error(serializer,
                            "Do not know how to serialize node type %d\n",
                            statement->predicate_type);
    return 1;
  }
  
  if(object_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE ||
     object_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS)
    object->count_as_object++;

  return 0;
}
/* serialize a statement */
static int
raptor_turtle_serialize_statement(raptor_serializer* serializer, 
                                  raptor_statement *statement)
{
  raptor_turtle_context* context = (raptor_turtle_context*)serializer->context;
  raptor_abbrev_subject* subject = NULL;
  raptor_abbrev_node* predicate = NULL;
  raptor_abbrev_node* object = NULL;
  int rv;
  raptor_term_type object_type;

  if(!(statement->subject->type == RAPTOR_TERM_TYPE_URI ||
       statement->subject->type == RAPTOR_TERM_TYPE_BLANK)) {
    raptor_log_error_formatted(serializer->world, RAPTOR_LOG_LEVEL_ERROR, NULL,
                               "Do not know how to serialize node type %d",
                               statement->subject->type);
    return 1;
  }  

  subject = raptor_abbrev_subject_lookup(context->nodes, context->subjects,
                                         context->blanks,
                                         statement->subject);
  if(!subject) {
    return 1;
  }

  object_type = statement->object->type;

  if(!(object_type == RAPTOR_TERM_TYPE_URI ||
       object_type == RAPTOR_TERM_TYPE_BLANK ||
       object_type == RAPTOR_TERM_TYPE_LITERAL)) {
    raptor_log_error_formatted(serializer->world, RAPTOR_LOG_LEVEL_ERROR, NULL,
                               "Cannot serialize a triple with object node type %d",
                               object_type);
    return 1;
  }

  object = raptor_abbrev_node_lookup(context->nodes, statement->object);
  if(!object)
    return 1;          


  if(statement->predicate->type == RAPTOR_TERM_TYPE_URI) {
    predicate = raptor_abbrev_node_lookup(context->nodes, statement->predicate);
    if(!predicate)
      return 1;
	      
    rv = raptor_abbrev_subject_add_property(subject, predicate, object);
    if(rv < 0) {
      raptor_log_error_formatted(serializer->world, RAPTOR_LOG_LEVEL_ERROR, NULL,
                                 "Unable to add properties to subject %p",
                                 subject);
      return rv;
    }
  
  } else {
    raptor_log_error_formatted(serializer->world, RAPTOR_LOG_LEVEL_ERROR, NULL,
                               "Do not know how to serialize node type %d",
                               statement->predicate->type);
    return 1;
  }
  
  if(object_type == RAPTOR_TERM_TYPE_URI ||
     object_type == RAPTOR_TERM_TYPE_BLANK)
    object->count_as_object++;

  return 0;
}