// file: $isip/class/mmedia/xt_03.cc
// version: $Id: xt_03.cc 9929 2004-12-31 02:42:05Z duncan $

#include "XMLToken.h"

// method: getAttributeValue
//
// arguments:
//  String arg_name: (input) the name of the attribute whose value is desired
//
// return: a String containing the value belonging to the attribute name,
//         or String::EMPTY if none is found.
//
String XMLToken::getAttributeValue(const String arg_name_a) const {
  
  // check for the presense of attributes in this token
  // if none are present, return a blank string
  //
  if(attributes_d.length() == 0) {
    return String::EMPTY;
  }
  
  // iterate through all the attributes
  //
  for(int i=0; i < attributes_d.length(); i++) {
    
    // if this attribute's name matches the arg_name_a
    // argument, return the value that goes with the name
    //
    if(attributes_d(i).first().eq(arg_name_a)) {
      return attributes_d(i).second();
    }
  }
  
  // if the attribute is not found, return an empty string
  //
  return String::EMPTY;
}

// method: setAttributes
//
// arguments:
//   byte** attrib_array: (input) a pointer to an  array containing
//     attribute names and values in an alternating fashion 
//
// return: a boolean indicating status
//
// Initilizes the token's attributes from an array of character strings
//
boolean XMLToken::setAttributes(const byte** attrib_array_a) {
  
  // check to see whether pointer is valid
  //
  if(!attrib_array_a) {
    return false;
  }
  
  // count the attribute name/value pairs
  // and resize the attributes vector so that it
  // may contain them all. Yes, the for loop
  // is supposed to be empty, the semicolon is not
  // a mistake.
  //
  int i;
  for(i=0; attrib_array_a[i]; i+=2);
  attributes_d.setCapacity(i);
  
  
  // the input array must be ordered a[0] = attrib name,
  // a[1] = attrib value, a[2] = second attrib name ...
  //
  for(i=0; attrib_array_a[i]; i+=2) {
    
    // declare a pair to store the attribute alongside its value
    //
    Pair<String, String> attribute;
    
    // the intermediate SysString variables are necessary because
    // the String class seems to have problems using (byte*) arguments
    //
    SysString sysattrib_name((byte*)attrib_array_a[i]);
    SysString sysvalue((byte*)attrib_array_a[i+1]);
    
    // convert the SysStrings to Strings
    //
    String attrib_name;
    attrib_name.assign(sysattrib_name);
    String value;
    value.assign(sysvalue);
    
    // store the name and value as a pair
    //
    attribute.assign(attrib_name, value);
    
    // place the name/value pair in the vector
    //
    attributes_d.concat(attribute);
  }
  
  // indicate success
  //
  return true;
}

// method: addAttribute
//
// arguments:
//   String attrib_name: (input) the name of the attribute to be added
//   String attrib_value: (input) the value of the attribute to be added
//
// return: a boolean indicating status
//
boolean XMLToken::addAttribute(String attrib_name_a, String attrib_value_a) {
  
  // store the input name and value as a pair
  //
  Pair<String, String> attrib(attrib_name_a, attrib_value_a);
  
  // add the pair to the array of attributes
  //
  attributes_d.concat(attrib);
  
  // indicate success
  //
  return true;
}

// method: removeAttribute
//
// arguments:
//   String attrib_name: (input) the name of the attribute to be
//     removed
//
// return: a boolean indicating status
//
boolean XMLToken::removeAttribute(String attrib_name_a) {
  
  // a variable to store the position of the attribute, if found
  //
  long index = Integral::NO_POS;
  
  // loop over all attributes
  //
  for(long i = 0; i < attributes_d.length(); i++) {
    
    // if the attribute is found, save the index
    //
    if(attributes_d(i).first().eq(attrib_name_a)) {
      index = i;
      break;
    }
    
  }
  
  // if the attribute was found, rebuild the attribute vector
  // without it. 
  //
  if(index != Integral::NO_POS) {
    
    Vector< Pair<String, String> > new_attribs;
    
    // rebuild the vector without the element to be
    // removed
    //
    for(long j = 0; j < attributes_d.length(); j++) {
      
      // only copy an attribute if it is not the one
      // to be removed
      //
      if(j != index) {
	new_attribs.concat(attributes_d(j));
      }
    }
    
    // store the modified set of attributes
    //
    setAttributes(new_attribs);
  }
  
  // indicate success
  //
  return true;
}
