Exemple #1
0
function handleParsedElement($parser, $pos, $name, $attrs)
{
    global $tag_stack;
    global $err;
    global $banner;
    global $img_conversion_enabled;
    global $skin;
    global $allow_skin_attribute;
    static $number_of_decks = 0;
    static $number_of_forms = 0;
    static $number_of_linksets = 0;
    static $markup_language = 0;
    static $raw_mode = false;
    if (function_exists("xml_get_current_line_number")) {
        $line = xml_get_current_line_number($parser);
    } else {
        $line = "???";
    }
    switch ($name) {
        case "HAWHAW":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_HAWHAW, $parser);
                $tag_stack->push(0, HAX_TAG_HAWHAW);
            } else {
                // HAX_PARSE_END
                $tag_stack->pop();
            }
            break;
        case "DECK":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_DECK, $parser);
                if ($number_of_decks++ > 0) {
                    error($err[5], $parser, $line);
                }
                // determine contructor arguments of HAW_deck
                if (isset($attrs["TITLE"])) {
                    $title = $attrs["TITLE"];
                } else {
                    $title = HAW_NOTITLE;
                }
                if (isset($attrs["ALIGN"]) && $attrs["ALIGN"] == "center") {
                    $alignment = HAW_ALIGN_CENTER;
                } elseif (isset($attrs["ALIGN"]) && $attrs["ALIGN"] == "right") {
                    $alignment = HAW_ALIGN_RIGHT;
                } else {
                    $alignment = HAW_ALIGN_LEFT;
                }
                $output = HAW_OUTPUT_AUTOMATIC;
                if (isset($attrs["OUTPUT"])) {
                    switch ($attrs["OUTPUT"]) {
                        case "bigscreen":
                            $output = HAW_OUTPUT_BIGSCREEN;
                            break;
                        case "wap":
                            $output = HAW_OUTPUT_WAP;
                            break;
                        case "hdml":
                            $output = HAW_OUTPUT_HDML;
                            break;
                        case "pda":
                            $output = HAW_OUTPUT_PDA;
                            break;
                        case "imode":
                            $output = HAW_OUTPUT_IMODE;
                            break;
                        case "mml":
                            $output = HAW_OUTPUT_MML;
                            break;
                        case "voicexml":
                            $output = HAW_OUTPUT_VOICEXML;
                            break;
                        case "xhtml":
                            $output = HAW_OUTPUT_XHTML;
                            break;
                    }
                }
                // initiate HAW_deck object
                $deck = new HAW_deck($title, $alignment, $output);
                $markup_language = $deck->ml;
                // modify HAW_deck objects according attribute list
                if (isset($attrs["REDIRECTION"])) {
                    $redirection = explode(";", $attrs["REDIRECTION"]);
                    $redirection[0] = trim($redirection[0]);
                    // strip whitespace
                    $redirection[1] = trim($redirection[1]);
                    if (isset($redirection[2])) {
                        $redirection[2] = trim(strtolower($redirection[2]));
                    }
                    if ($redirection[0] < 1 || $redirection[0] > 3600) {
                        error($err[3], $parser, $line);
                    }
                    // invalid time value
                    if (substr(strtolower($redirection[1]), 0, 4) != "url=") {
                        error($err[3], $parser, $line);
                    }
                    // invalid URL declaration
                    if (isset($redirection[2]) && $redirection[2] == "proxy=no") {
                        // redirect directly to target (needed for HawTags)
                        $deck->set_redirection($redirection[0], substr($redirection[1], 4));
                    } else {
                        // redirect via HAWXY
                        $deck->set_redirection($redirection[0], determine_url(qualify_url(substr($redirection[1], 4))));
                    }
                }
                if (isset($attrs["CACHE"]) && strtolower($attrs["CACHE"]) == "no") {
                    $deck->disable_cache();
                }
                if (isset($attrs["CHARSET"])) {
                    $deck->set_charset($attrs["CHARSET"]);
                }
                if (isset($attrs["LANGUAGE"])) {
                    $deck->set_language($attrs["LANGUAGE"]);
                }
                if (isset($attrs["CSS"])) {
                    $deck->set_css($attrs["CSS"]);
                }
                if (isset($attrs["CSS_CLASS"])) {
                    $deck->set_css_class($attrs["CSS_CLASS"]);
                }
                if (isset($attrs["BACKGROUND"])) {
                    $deck->set_background($attrs["BACKGROUND"]);
                }
                if (isset($attrs["BGCOLOR"])) {
                    $deck->set_bgcolor($attrs["BGCOLOR"]);
                }
                if (isset($attrs["SIZE"])) {
                    $deck->set_size($attrs["SIZE"]);
                }
                if (isset($attrs["COLOR"])) {
                    $deck->set_color($attrs["COLOR"]);
                }
                if (isset($attrs["LINK_COLOR"])) {
                    $deck->set_link_color($attrs["LINK_COLOR"]);
                }
                if (isset($attrs["VLINK_COLOR"])) {
                    $deck->set_vlink_color($attrs["VLINK_COLOR"]);
                }
                if (isset($attrs["LINK_BRACKETS"]) && strtolower($attrs["LINK_BRACKETS"]) == "no") {
                    $deck->use_link_brackets(false);
                }
                if (isset($attrs["FACE"])) {
                    $deck->set_face($attrs["FACE"]);
                }
                if (isset($attrs["WAPHOME"])) {
                    $deck->set_waphome($attrs["WAPHOME"]);
                } else {
                    $deck->set_waphome("http://" . getenv("HTTP_HOST") . getenv("REQUEST_URI"));
                }
                if (isset($attrs["VOICE_JINGLE"])) {
                    $deck->set_voice_jingle($attrs["VOICE_JINGLE"]);
                }
                if (isset($attrs["SKIN"]) && $allow_skin_attribute) {
                    if (strtolower($attrs["SKIN"]) == "none") {
                        $deck->use_simulator(HAW_SIM_NONE);
                    } else {
                        if (strtolower($attrs["SKIN"]) == "classic") {
                            $deck->use_simulator(HAW_SIM_CLASSIC);
                        } else {
                            $deck->use_simulator($attrs["SKIN"]);
                        }
                    }
                } else {
                    $deck->use_simulator($skin);
                }
                // display banners on top of simulator device
                while (list($key, $val) = each($banner)) {
                    // edit config file for banner control
                    $top_banner[$key] = new HAW_banner($val["img"], $val["url"], $val["alt"]);
                    $top_banner[$key]->set_size($val["width"], $val["height"]);
                    $deck->add_banner($top_banner[$key], HAW_TOP);
                }
                $tag_stack->push($deck, HAX_TAG_DECK);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                $deck = $element["element"];
                $deck->create_page();
            }
            break;
        case "FORM":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_FORM, $parser);
                if ($number_of_forms++ > 0) {
                    error($err[9], $parser, $line);
                }
                if (!isset($attrs["ACTION"])) {
                    error("<form> " . $err[7] . " action", $parser, $line);
                }
                // action attribute is missing
                // initiate HAW_form object
                if (isset($attrs["PROXY"]) && strtolower($attrs["PROXY"]) == "no") {
                    // send form data to action script (needed for HawTags)
                    $form = new HAW_form($attrs["ACTION"]);
                } else {
                    // send form data to hawxy server
                    $form = new HAW_form($_SERVER['SCRIPT_NAME']);
                    // add info about XML source where form input has to be propagated to
                    $hidden = new HAW_hidden("code", qualify_url($attrs["ACTION"]));
                    $form->add_hidden($hidden);
                }
                $tag_stack->push($form, HAX_TAG_FORM);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_form object
                $form = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck)
                $base_element = $element["element"];
                $base_element->add_form($form);
                // add HAW_form to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "TEXT":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_TEXT, $parser);
                $format = "HAW_TEXTFORMAT_NORMAL";
                if (isset($attrs["BOLD"]) && strtolower($attrs["BOLD"]) == "yes") {
                    $format |= HAW_TEXTFORMAT_BOLD;
                }
                if (isset($attrs["ITALIC"]) && strtolower($attrs["ITALIC"]) == "yes") {
                    $format |= HAW_TEXTFORMAT_ITALIC;
                }
                if (isset($attrs["UNDERLINE"]) && strtolower($attrs["UNDERLINE"]) == "yes") {
                    $format |= HAW_TEXTFORMAT_UNDERLINE;
                }
                if (isset($attrs["BIG"]) && strtolower($attrs["BIG"]) == "yes") {
                    $format |= HAW_TEXTFORMAT_BIG;
                }
                if (isset($attrs["SMALL"]) && strtolower($attrs["SMALL"]) == "yes") {
                    $format |= HAW_TEXTFORMAT_SMALL;
                }
                if (isset($attrs["BOXED"]) && strtolower($attrs["BOXED"]) == "yes") {
                    $format |= HAW_TEXTFORMAT_BOXED;
                }
                $text = new HAW_text("", $format);
                if (isset($attrs["BR"]) && $attrs["BR"] >= 0) {
                    $text->set_br($attrs["BR"] + 0);
                }
                // convert string to int!
                if (isset($attrs["CSS_CLASS"])) {
                    $text->set_css_class($attrs["CSS_CLASS"]);
                }
                if (isset($attrs["COLOR"])) {
                    $textcolor = $attrs["COLOR"];
                    if (isset($attrs["BOXCOLOR"])) {
                        $boxcolor = $attrs["BOXCOLOR"];
                    } else {
                        $boxcolor = "";
                    }
                    $text->set_color($textcolor, $boxcolor);
                }
                $tag_stack->push($text, HAX_TAG_TEXT);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_text object
                $text = $element["element"];
                if (!$text->voice_text) {
                    $text->voice_text = $text->text;
                }
                // update voice_text if not already set
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_form, ...)
                $base_element = $element["element"];
                if ($element["tag"] == HAX_TAG_TD) {
                    // include HAW_text object in HAX_td pseudo class
                    $base_element->element = $text;
                    $base_element->tag = HAX_TAG_TEXT;
                } else {
                    $base_element->add_text($text);
                }
                // add HAW_text to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "IMG":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_IMAGE, $parser);
                if (!($alt = $attrs["ALT"])) {
                    error("<img> " . $err[7] . " alt", $parser, $line);
                }
                // alt attribute is missing
                if (isset($attrs["SRC"])) {
                    // source attribute ==> perform automatic image conversion
                    if (!$img_conversion_enabled) {
                        error($err[13], $parser, $line);
                    }
                    // image conversion deactivated per config
                    if (!function_exists("ImageTypes")) {
                        error($err[13], $parser, $line);
                    }
                    // GD is not loaded
                    if (!(ImageTypes() & (IMG_PNG | IMG_WBMP))) {
                        error($err[13], $parser, $line);
                    }
                    // not all necessary image types supported
                    $source = $attrs["SRC"];
                    $extension = strtolower(substr($source, -4));
                    $accept = strtolower($_SERVER['HTTP_ACCEPT']);
                    if ($extension == ".gif" && (strstr($accept, "image/gif") || $markup_language == HAW_HTML && !strstr($accept, "image/png")) || $extension == ".png" && (strstr($accept, "image/png") || $markup_language == HAW_HTML) || $extension == "wbmp" && $markup_language == HAW_WML) {
                        // requesting browser accepts given src image file
                        // ==> no conversion required
                        $src_html = $source;
                        $src_wbmp = $source;
                    } else {
                        // session-controlled image conversion
                        // convert images of HAWHAW XML files only
                        // (we don't want to act as conversion server for the whole world!)
                        static $img_counter = 0;
                        $varname = "i" . $img_counter;
                        session_register($varname);
                        $_SESSION[$varname] = $attrs["SRC"];
                        $_SESSION['img_ml'] = $markup_language;
                        //$url = sprintf("%s?index=%d", $_SERVER['PHP_SELF'] , $img_counter);
                        // auto-appending of SID does not work in some environments ?!?!?
                        // PHPSESSID may appear twice in url - and if? ...
                        $url = sprintf("%s?index=%d&amp;%s", $_SERVER['PHP_SELF'], $img_counter, SID);
                        // create image with session ID instead of image URL's
                        // ==> hawxy script will immediately receive a new request
                        //     and will create appropriate image on the fly
                        $src_html = $url;
                        $src_wbmp = $url;
                        $img_counter++;
                    }
                }
                if (!isset($src_wbmp) && !isset($attrs["WBMP"])) {
                    error("<img> " . $err[7] . " wbmp", $parser, $line);
                } elseif (isset($attrs["WBMP"])) {
                    $src_wbmp = $attrs["WBMP"];
                }
                // explicitely given WBMP file has precedence
                if (!isset($src_html) && !isset($attrs["HTML"])) {
                    error("<img> " . $err[7] . " html", $parser, $line);
                } elseif (isset($attrs["HTML"])) {
                    $src_html = $attrs["HTML"];
                }
                // explicitely given HTML file has precedence
                if (isset($attrs["BMP"])) {
                    $image = new HAW_image($src_wbmp, $src_html, $alt, $attrs["BMP"]);
                } else {
                    $image = new HAW_image($src_wbmp, $src_html, $alt);
                }
                if (isset($attrs["HTML"]) && isset($attrs["HTML_WIDTH"])) {
                    $image->set_html_width($attrs["HTML_WIDTH"]);
                }
                if (isset($attrs["HTML"]) && isset($attrs["HTML_HEIGHT"])) {
                    $image->set_html_height($attrs["HTML_HEIGHT"]);
                }
                if (isset($attrs["BR"]) && $attrs["BR"] >= 0) {
                    $image->set_br($attrs["BR"] + 0);
                }
                // convert string to int!
                if (isset($attrs["LOCALSRC"])) {
                    $image->use_localsrc($attrs["LOCALSRC"]);
                }
                if (isset($attrs["CHTML_ICON"])) {
                    $image->use_chtml_icon($attrs["CHTML_ICON"] + 0);
                }
                // convert string to int!
                if (isset($attrs["MML_ICON"]) && strlen($attrs["MML_ICON"]) == 2) {
                    $image->use_mml_icon($attrs["MML_ICON"]);
                }
                $tag_stack->push($image, HAX_TAG_IMAGE);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_image object
                $image = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_form, ...)
                $base_element = $element["element"];
                if ($element["tag"] == HAX_TAG_TD) {
                    // include HAW_text object in HAX_td pseudo class
                    $base_element->element = $image;
                    $base_element->tag = HAX_TAG_IMAGE;
                } else {
                    $base_element->add_image($image);
                }
                // add HAW_image to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "INPUT":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_INPUT, $parser);
                if (!($name = $attrs["NAME"])) {
                    error("<input> " . $err[7] . " name", $parser, $line);
                }
                // name attribute is missing
                if (isset($attrs["FORMAT"])) {
                    $input = new HAW_input($name, $attrs["VALUE"], $attrs["LABEL"], $attrs["FORMAT"]);
                } else {
                    $input = new HAW_input($name, $attrs["VALUE"], $attrs["LABEL"]);
                }
                if (isset($attrs["SIZE"])) {
                    $input->set_size($attrs["SIZE"]);
                }
                if (isset($attrs["MAXLENGTH"])) {
                    $input->set_maxlength($attrs["MAXLENGTH"]);
                }
                if (isset($attrs["TYPE"]) && strtolower($attrs["TYPE"]) == "password") {
                    $input->set_type(HAW_INPUT_PASSWORD);
                }
                if (isset($attrs["MODE"])) {
                    if (strtolower($attrs["MODE"]) == "alphabet") {
                        $input->set_mode(HAW_INPUT_ALPHABET);
                    }
                    if (strtolower($attrs["MODE"]) == "katakana") {
                        $input->set_mode(HAW_INPUT_KATAKANA);
                    }
                    if (strtolower($attrs["MODE"]) == "hiragana") {
                        $input->set_mode(HAW_INPUT_HIRAGANA);
                    }
                    if (strtolower($attrs["MODE"]) == "numeric") {
                        $input->set_mode(HAW_INPUT_NUMERIC);
                    }
                }
                if (isset($attrs["BR"]) && $attrs["BR"] >= 0) {
                    $input->set_br($attrs["BR"] + 0);
                }
                // convert string to int!
                if (isset($attrs["VOICE_TYPE"])) {
                    $input->set_voice_type($attrs["VOICE_TYPE"]);
                }
                if (isset($attrs["VOICE_GRAMMAR_SRC"])) {
                    // set external grammar
                    if (isset($attrs["VOICE_GRAMMAR_TYPE"])) {
                        $input->set_voice_grammar($attrs["VOICE_GRAMMAR_SRC"], $attrs["VOICE_GRAMMAR_TYPE"]);
                    } else {
                        $input->set_voice_grammar($attrs["VOICE_GRAMMAR_SRC"]);
                    }
                    // requires HAWHAW V5.5 or higher!
                }
                $tag_stack->push($input, HAX_TAG_INPUT);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_input object
                $input = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_form)
                $base_element = $element["element"];
                $base_element->add_input($input);
                // add HAW_input to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "RADIO":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_RADIO, $parser);
                if (!($name = $attrs["NAME"])) {
                    error("<radio> " . $err[7] . " name", $parser, $line);
                }
                // name attribute is missing
                $radio = new HAW_radio($name);
                $tag_stack->push($radio, HAX_TAG_RADIO);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_radio object
                $radio = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_form)
                $base_element = $element["element"];
                $base_element->add_radio($radio);
                // add HAW_radio to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "BUTTON":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_BUTTON, $parser);
                if (!($label = $attrs["LABEL"])) {
                    error("<button> " . $err[7] . " label", $parser, $line);
                }
                // label attribute is missing
                if (!($value = $attrs["VALUE"])) {
                    error("<button> " . $err[7] . " value", $parser, $line);
                }
                // value attribute is missing
                if (isset($attrs["CHECKED"]) && strtolower($attrs["CHECKED"]) == "yes") {
                    $checked = HAW_CHECKED;
                } else {
                    $checked = HAW_NOTCHECKED;
                }
                $element = $tag_stack->pop();
                // pop base object (HAW_radio)
                $base_element = $element["element"];
                $base_element->add_button($label, $value, $checked);
                // add button properties
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            } else {
                // HAX_PARSE_END
                // nothing to do any more
            }
            break;
        case "CHECKBOX":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_CHECKBOX, $parser);
                if (!($name = $attrs["NAME"])) {
                    error("<checkbox> " . $err[7] . " name", $parser, $line);
                }
                // name attribute is missing
                if (!($value = $attrs["VALUE"])) {
                    error("<checkbox> " . $err[7] . " value", $parser, $line);
                }
                // value attribute is missing
                if (!($label = $attrs["LABEL"])) {
                    error("<checkbox> " . $err[7] . " label", $parser, $line);
                }
                // label attribute is missing
                if (isset($attrs["CHECKED"]) && strtolower($attrs["CHECKED"]) == "yes") {
                    $checked = HAW_CHECKED;
                } else {
                    $checked = HAW_NOTCHECKED;
                }
                $checkbox = new HAW_checkbox($name, $value, $label, $checked);
                $tag_stack->push($checkbox, HAX_TAG_CHECKBOX);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_checkbox object
                $checkbox = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_form)
                $base_element = $element["element"];
                $base_element->add_checkbox($checkbox);
                // add HAW_checkbox to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "SELECT":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_SELECT, $parser);
                if (!($name = $attrs["NAME"])) {
                    error("<select> " . $err[7] . " name", $parser, $line);
                }
                // name attribute is missing
                if (strtolower($attrs["TYPE"]) == "popup") {
                    $select = new HAW_select($name, HAW_SELECT_POPUP);
                } elseif (strtolower($attrs["TYPE"]) == "spin") {
                    $select = new HAW_select($name, HAW_SELECT_SPIN);
                } else {
                    $select = new HAW_select($name);
                }
                $tag_stack->push($select, HAX_TAG_SELECT);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_select object
                $select = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_form)
                $base_element = $element["element"];
                $base_element->add_select($select);
                // add HAW_select to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "OPTION":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_OPTION, $parser);
                if (!($label = $attrs["LABEL"])) {
                    error("<option> " . $err[7] . " label", $parser, $line);
                }
                // label attribute is missing
                if (!($value = $attrs["VALUE"])) {
                    error("<option> " . $err[7] . " value", $parser, $line);
                }
                // value attribute is missing
                if (isset($attrs["SELECTED"]) && strtolower($attrs["SELECTED"]) == "yes") {
                    $selected = HAW_SELECTED;
                } else {
                    $selected = HAW_NOTSELECTED;
                }
                $element = $tag_stack->pop();
                // pop base object (HAW_select)
                $base_element = $element["element"];
                $base_element->add_option($label, $value, $selected);
                // add option properties
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            } else {
                // HAX_PARSE_END
                // nothing to do any more
            }
            break;
        case "HIDDEN":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_HIDDEN, $parser);
                if (!($name = $attrs["NAME"])) {
                    error("<hidden> " . $err[7] . " name", $parser, $line);
                }
                // name attribute is missing
                if (!($value = $attrs["VALUE"])) {
                    error("<hidden> " . $err[7] . " value", $parser, $line);
                }
                // value attribute is missing
                $hidden = new HAW_hidden($name, $value);
                $element = $tag_stack->pop();
                // pop base object (HAW_form)
                $base_element = $element["element"];
                $base_element->add_hidden($hidden);
                // add HAW_hidden to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            } else {
                // HAX_PARSE_END
                // nothing to do any more
            }
            break;
        case "SUBMIT":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_SUBMIT, $parser);
                if (!($label = $attrs["LABEL"])) {
                    error("<submit> " . $err[7] . " label", $parser, $line);
                }
                // label attribute is missing
                if (isset($attrs["NAME"])) {
                    $submit = new HAW_submit($label, $attrs["NAME"]);
                } else {
                    $submit = new HAW_submit($label);
                }
                $tag_stack->push($submit, HAX_TAG_SUBMIT);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_submit object
                $submit = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_form)
                $base_element = $element["element"];
                $base_element->add_submit($submit);
                // add HAW_submit to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "A":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_LINK, $parser);
                if (!isset($attrs["HREF"])) {
                    error("<a> " . $err[7] . " href", $parser, $line);
                }
                // href attribute is missing
                if (isset($attrs["PROXY"]) && strtolower($attrs["PROXY"]) == "no") {
                    $url = $attrs["HREF"];
                } else {
                    $url = determine_url(qualify_url($attrs["HREF"]));
                }
                // let HAWHAW proxy retrieve href
                if (isset($attrs["TITLE"])) {
                    $link = new HAW_link("", $url, $attrs["TITLE"]);
                } else {
                    $link = new HAW_link("", $url);
                }
                if (isset($attrs["BR"]) && $attrs["BR"] >= 0) {
                    $link->set_br($attrs["BR"] + 0);
                }
                // convert string to int!
                if (isset($attrs["CSS_CLASS"])) {
                    $link->set_css_class($attrs["CSS_CLASS"]);
                }
                if (isset($attrs["VOICE_DTMF"])) {
                    $link->set_voice_dtmf($attrs["VOICE_DTMF"]);
                }
                if (isset($attrs["VOICE_INPUT"])) {
                    $link->set_voice_input($attrs["VOICE_INPUT"]);
                } else {
                    unset($link->voice_input);
                }
                // we must destinguish missing attr from empty string
                if (isset($attrs["VOICE_TIMEOUT"])) {
                    $link->set_voice_timeout($attrs["VOICE_TIMEOUT"] + 0);
                }
                // convert string to int!
                $tag_stack->push($link, HAX_TAG_LINK);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_link object
                $link = $element["element"];
                if (!$link->voice_text) {
                    $link->voice_text = $link->label;
                }
                // update voice_text if not already set
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_linkset, ...)
                $base_element = $element["element"];
                if ($element["tag"] == HAX_TAG_TD) {
                    // include HAW_link object in HAX_td pseudo class
                    $base_element->element = $link;
                    $base_element->tag = HAX_TAG_LINK;
                } else {
                    $base_element->add_link($link);
                }
                // add HAW_link to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "LINKSET":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_LINKSET, $parser);
                if ($number_of_linksets++ > 0) {
                    error($err[8], $parser, $line);
                }
                $linkset = new HAW_linkset();
                $tag_stack->push($linkset, HAX_TAG_LINKSET);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_linkset object
                $linkset = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck)
                $base_element = $element["element"];
                $base_element->add_linkset($linkset);
                // add HAW_linkset to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "TABLE":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_TABLE, $parser);
                $table = new HAW_table();
                $tag_stack->push($table, HAX_TAG_TABLE);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_table object
                $table = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_form, ...)
                $base_element = $element["element"];
                $base_element->add_table($table);
                // add HAW_table to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "TR":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_ROW, $parser);
                $row = new HAW_row();
                $tag_stack->push($row, HAX_TAG_ROW);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_row object
                $row = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_table)
                $base_element = $element["element"];
                $base_element->add_row($row);
                // add HAW_row to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "TD":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_TD, $parser);
                $td = new HAX_td();
                $tag_stack->push($td, HAX_TAG_TD);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAX_td object
                $td = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_row)
                $base_element = $element["element"];
                $base_element->add_column($td->element);
                // add included element of HAX_td to row
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "HR":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_RULE, $parser);
                if (isset($attrs["WIDTH"]) && isset($attrs["SIZE"])) {
                    $rule = new HAW_rule($attrs["WIDTH"], $attrs["SIZE"]);
                } elseif (isset($attrs["WIDTH"])) {
                    $rule = new HAW_rule($attrs["WIDTH"]);
                } elseif (isset($attrs["SIZE"])) {
                    $rule = new HAW_rule("100%", $attrs["SIZE"]);
                } else {
                    $rule = new HAW_rule();
                }
                $tag_stack->push($rule, HAX_TAG_RULE);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_rule object
                $rule = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck or HAW_form)
                $base_element = $element["element"];
                $base_element->add_rule($rule);
                // add HAW_rule to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "PHONE":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_PHONE, $parser);
                if (isset($attrs["TITLE"])) {
                    $phone = new HAW_phone("", $attrs["TITLE"]);
                } else {
                    $phone = new HAW_phone("");
                }
                if (isset($attrs["CSS_CLASS"])) {
                    $phone->set_css_class($attrs["CSS_CLASS"]);
                }
                if (isset($attrs["VOICE_INPUT"])) {
                    $phone->set_voice_input($attrs["VOICE_INPUT"]);
                }
                if (isset($attrs["VOICE_DTMF"])) {
                    $phone->set_voice_dtmf($attrs["VOICE_DTMF"]);
                }
                if (isset($attrs["VOICE_TIMEOUT"])) {
                    $phone->set_voice_timeout($attrs["VOICE_TIMEOUT"] + 0);
                }
                // convert string to int!
                if (isset($attrs["BR"]) && $attrs["BR"] >= 0) {
                    $phone->set_br($attrs["BR"] + 0);
                }
                // convert string to int!
                $tag_stack->push($phone, HAX_TAG_PHONE);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_phone object
                $phone = $element["element"];
                if (!$phone->voice_text) {
                    $phone->voice_text = $phone->label;
                }
                // update voice_text if not already set
                $element = $tag_stack->pop();
                // pop base object (HAW_deck)
                $base_element = $element["element"];
                $base_element->add_phone($phone);
                // add HAW_phone to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "VOICE_TEXT":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_VOICE_TEXT, $parser);
                if (isset($attrs["AUDIO_SRC"])) {
                    $audio_src = $attrs["AUDIO_SRC"];
                } else {
                    $audio_src = "";
                }
                $event = new HAX_voice_event(HAX_TAG_VOICE_TEXT, "", $audio_src);
                $tag_stack->push($event, HAX_TAG_VOICE_TEXT);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAX_voice_event object
                $event = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_input, ...)
                $base_element = $element["element"];
                // set voice text for base element
                $base_element->set_voice_text($event->text, $event->audio_src);
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "VOICE_HELP":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_VOICE_HELP, $parser);
                if (isset($attrs["AUDIO_SRC"])) {
                    $audio_src = $attrs["AUDIO_SRC"];
                } else {
                    $audio_src = "";
                }
                if (isset($attrs["URL"])) {
                    $url = $attrs["URL"];
                } else {
                    $url = "";
                }
                $event = new HAX_voice_event(HAX_TAG_VOICE_HELP, "", $audio_src, $url);
                $tag_stack->push($event, HAX_TAG_VOICE_HELP);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAX_voice_event object
                $event = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_input, ...)
                $base_element = $element["element"];
                // activate voice help for base element
                $base_element->set_voice_help($event->text, $event->audio_src, $event->url);
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "VOICE_NOMATCH":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_VOICE_NOMATCH, $parser);
                if (isset($attrs["AUDIO_SRC"])) {
                    $audio_src = $attrs["AUDIO_SRC"];
                } else {
                    $audio_src = "";
                }
                if (isset($attrs["URL"])) {
                    $url = $attrs["URL"];
                } else {
                    $url = "";
                }
                $event = new HAX_voice_event(HAX_TAG_VOICE_NOMATCH, "", $audio_src, $url);
                $tag_stack->push($event, HAX_TAG_VOICE_NOMATCH);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAX_voice_event object
                $event = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_input, ...)
                $base_element = $element["element"];
                // activate voice nomatch for base element
                $base_element->set_voice_nomatch($event->text, $event->audio_src, $event->url);
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "VOICE_NOINPUT":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_VOICE_NOINPUT, $parser);
                if (isset($attrs["AUDIO_SRC"])) {
                    $audio_src = $attrs["AUDIO_SRC"];
                } else {
                    $audio_src = "";
                }
                if (isset($attrs["URL"])) {
                    $url = $attrs["URL"];
                } else {
                    $url = "";
                }
                $event = new HAX_voice_event(HAX_TAG_VOICE_NOINPUT, "", $audio_src, $url);
                $tag_stack->push($event, HAX_TAG_VOICE_NOINPUT);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAX_voice_event object
                $event = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck, HAW_input, ...)
                $base_element = $element["element"];
                // activate voice noinput for base element
                $base_element->set_voice_noinput($event->text, $event->audio_src, $event->url);
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        case "RAW":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_RAW, $parser);
                if (!isset($attrs["MARKUP_LANGUAGE"])) {
                    error("<raw> " . $err[7] . " markup_language", $parser, $line);
                }
                // markup_language attribute is missing
                if (strtolower($attrs["MARKUP_LANGUAGE"]) == "html") {
                    if (HAX_RAW_HTML_ALLOWED == false) {
                        error($err[4], $parser, $line);
                    }
                    // raw html not allowed
                    $raw = new HAW_raw(HAW_HTML, "");
                } elseif (strtolower($attrs["MARKUP_LANGUAGE"]) == "wml") {
                    if (HAX_RAW_WML_ALLOWED == false) {
                        error($err[4], $parser, $line);
                    }
                    // raw wml not allowed
                    $raw = new HAW_raw(HAW_WML, "");
                } elseif (strtolower($attrs["MARKUP_LANGUAGE"]) == "hdml") {
                    if (HAX_RAW_HDML_ALLOWED == false) {
                        error($err[4], $parser, $line);
                    }
                    // raw hdml not allowed
                    $raw = new HAW_raw(HAW_HDML, "");
                } elseif (strtolower($attrs["MARKUP_LANGUAGE"]) == "voicexml") {
                    if (HAX_RAW_VXML_ALLOWED == false) {
                        error($err[4], $parser, $line);
                    }
                    // raw VoiceXML not allowed
                    $raw = new HAW_raw(HAW_VXML, "");
                } else {
                    error("<raw> " . $err[14] . " markup_language", $parser, $line);
                }
                // invalid markup_language attribute
                $tag_stack->push($raw, HAX_TAG_RAW);
                $raw_mode = true;
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_raw object
                $raw = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck or HAW_form)
                $base_element = $element["element"];
                $base_element->add_raw($raw);
                // add HAW_raw to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
                $raw_mode = false;
            }
            break;
        case "PLUGIN":
            if ($pos == HAX_PARSE_BEGIN) {
                check_state(HAX_TAG_RAW, $parser);
                if (!isset($attrs["NAME"])) {
                    error("<plugin> " . $err[7] . " name", $parser, $line);
                }
                // markup_language attribute is missing
                // determine filename of plugin php script
                // must be located in the same directory as hawxy.php
                $plugin_filename = dirname(__FILE__) . '/' . HAX_PLUGIN_PREFIX . $attrs["NAME"] . '.php';
                // security check 1: test if plugin file exists
                if (!file_exists($plugin_filename)) {
                    error($err[15] . $attrs["NAME"], $parser, $line);
                }
                // plugin not found
                // setup php instructions
                $php_cmd = "require_once(\"{$plugin_filename}\");" . '$udef = new ' . HAX_PLUGIN_PREFIX . $attrs["NAME"] . "();";
                while (list($key, $val) = each($attrs)) {
                    // security check 2: allow alphanumeric characters only!
                    $param = preg_replace('/[^\\w]/', "", $val);
                    if (strtolower($key) != "name") {
                        $php_cmd .= '$udef->set_' . strtolower($key) . '(\'' . $param . '\');';
                    }
                }
                // create user-defined object and call set methods
                if (eval($php_cmd) === false) {
                    // eval might exit silently in case of fatal errors within the plugin!
                    error($err[16] . " " . $attrs["NAME"], $parser, $line);
                }
                // error in plugin's php code
                $tag_stack->push($udef, HAX_TAG_PLUGIN);
            } else {
                // HAX_PARSE_END
                $element = $tag_stack->pop();
                // pop HAW_plugin object
                $udef = $element["element"];
                $element = $tag_stack->pop();
                // pop base object (HAW_deck or HAW_form)
                $base_element = $element["element"];
                $base_element->add_userdefined($udef);
                // add HAW_plugin to base object
                $tag_stack->push($base_element, $element["tag"]);
                // re-push base object
            }
            break;
        default:
            if ($raw_mode == true) {
                // only in raw mode unknown tags will be handled
                $element = $tag_stack->pop();
                if ($element["tag"] == HAX_TAG_RAW) {
                    if ($pos == HAX_PARSE_BEGIN) {
                        // copy opening (raw) tag with all its attributes
                        $element["element"]->code .= "<" . strtolower($name);
                        while (list($key, $value) = each($attrs)) {
                            $element["element"]->code .= " " . strtolower($key) . "=\"" . $value . "\"";
                        }
                        $element["element"]->code .= ">";
                    } else {
                        // HAX_PARSE_END
                        $element["element"]->code .= "</" . strtolower($name) . ">";
                    }
                }
                $tag_stack->push($element["element"], $element["tag"]);
            }
            break;
    }
}