// Appends all applicable non-tag descendants of this node into the given element list.
void StyleSheetNode::GetApplicableDescendants(std::vector< const StyleSheetNode* >& applicable_nodes, const Element* element) const
{
	// Check if this node matches this element.
	switch (type)
	{
		ROCKET_UNUSED_SWITCH_ENUM(NUM_NODE_TYPES);
		case ROOT:
		case TAG:
		{
			// These nodes always match.
		}
		break;

		case CLASS:
		{
			if (!element->IsClassSet(name))
				return;
		}
		break;

		case ID:
		{
			if (name != element->GetId())
				return;
		}
		break;

		case PSEUDO_CLASS:
		{
			if (!element->IsPseudoClassSet(name))
				return;
		}
		break;

		case STRUCTURAL_PSEUDO_CLASS:
		{
			if (selector == NULL)
				return;

			if (!selector->IsApplicable(element, a, b))
				return;
		}
		break;
	}

	if (properties.GetNumProperties() > 0 ||
		!children[PSEUDO_CLASS].empty())
		applicable_nodes.push_back(this);

	for (int i = CLASS; i < NUM_NODE_TYPES; i++)
	{
		// Don't recurse into pseudo-classes; they can't be built into the root definition.
		if (i == PSEUDO_CLASS)
			continue;

		for (NodeMap::const_iterator j = children[i].begin(); j != children[i].end(); ++j)
			(*j).second->GetApplicableDescendants(applicable_nodes, element);
	}
}
// Returns an element's line height, if it has a font defined.
int ElementUtilities::GetLineHeight(Element* element)
{
	FontFaceHandle* font_face_handle = element->GetFontFaceHandle();
	if (font_face_handle == NULL)
		return 0;

	int line_height = font_face_handle->GetLineHeight();
	float inch = element->GetRenderInterface()->GetPixelsPerInch();
	const Property* line_height_property = element->GetLineHeightProperty();

	switch (line_height_property->unit)
	{
	ROCKET_UNUSED_SWITCH_ENUM(Property::UNKNOWN);
	ROCKET_UNUSED_SWITCH_ENUM(Property::KEYWORD);
	ROCKET_UNUSED_SWITCH_ENUM(Property::STRING);
	ROCKET_UNUSED_SWITCH_ENUM(Property::COLOUR);
	ROCKET_UNUSED_SWITCH_ENUM(Property::ABSOLUTE_UNIT);
	ROCKET_UNUSED_SWITCH_ENUM(Property::PPI_UNIT);
	ROCKET_UNUSED_SWITCH_ENUM(Property::RELATIVE_UNIT);
	case Property::NUMBER:
	case Property::EM:
		// If the property is a straight number or an em measurement, then it scales the line height.
		return Math::Round(line_height_property->value.Get< float >() * line_height);
	case Property::PERCENT:
		// If the property is a percentage, then it scales the line height.
		return Math::Round(line_height_property->value.Get< float >() * line_height * 0.01f);
	case Property::PX:
		// A px measurement.
		return Math::Round(line_height_property->value.Get< float >());
	case Property::INCH:
		// Values based on pixels-per-inch.
		return Math::Round(line_height_property->value.Get< float >() * inch);
	case Property::CM:
		return Math::Round(line_height_property->value.Get< float >() * inch * (1.0f / 2.54f));
	case Property::MM:
		return Math::Round(line_height_property->value.Get< float >() * inch * (1.0f / 25.4f));
	case Property::PT:
		return Math::Round(line_height_property->value.Get< float >() * inch * (1.0f / 72.0f));
	case Property::PC:
		return Math::Round(line_height_property->value.Get< float >() * inch * (1.0f / 6.0f));
	}

	return 0;
}