<?php
namespace NitroPack\HtmlDom;

class ScriptNode extends Node {
    private $strings = array();

    public function parseDom(&$iterator) {
        $inScriptString = false;
        $inScriptComment = false;
        $inScriptRegex = false;
        $inSpecialScriptContext = false;
        $scriptQuoteChar = '';
        $scriptCommentType = 'oneline';
        $string = "";

        $this->containingElement = $this;

        if ($iterator->key() > 0) {
            $iterator->next();
        } 

        foreach ($iterator as $char) {
            if ($char == '<') {
                if (!$inScriptString && strtolower($iterator->peek(7)) == '/script') {
                    $iterator->consume(8);
                    $this->readTillClosing($iterator);
                    return;
                }
            } else if ($inScriptComment) {
                $this->innerText .= $char;
                if ($scriptCommentType == 'oneline' && $char == "\n") {
                    $inScriptComment = false;
                } elseif ($scriptCommentType == 'multiline' && $char == "*" && $iterator->peek() == '/') {
                    $inScriptComment = false;
                    $this->innerText .= '/';
                    $iterator->consume(1);
                }
                continue;
            } else {
                if (($char == '"' || $char == "'")) {
                    if (!$inScriptString && !$inScriptComment && !$inScriptRegex) {
                        $inScriptString = true;
                        $scriptQuoteChar = $char;
                    } elseif ($char == $scriptQuoteChar) {
                        $inScriptString = false;
                        $scriptQuoteChar = '';
                    }
                } elseif ($inScriptString && $char == '\\') {
                    if ($iterator->peek() == $scriptQuoteChar) {
                        $char .= $scriptQuoteChar;// Append to the char so this can be included in the innerText
                        $iterator->consume(1);
                    }
                } elseif (!$inScriptString && $char == '/') {
                    switch ($iterator->peek()) {
                    case '/':
                        $char .= '/';// Append to the char so this can be included in the innerText
                        $iterator->consume(1);
                        $inScriptComment = true;
                        $scriptCommentType = 'oneline';
                        break;
                    case '*':
                        $char .= '*';// Append to the char so this can be included in the innerText
                        $iterator->consume(1);
                        $inScriptComment = true;
                        $scriptCommentType = 'multiline';
                        break;
                    default:
                        if ($inScriptRegex) {
                            $inScriptRegex = false;
                        } else if ($inSpecialScriptContext) {
                            $inScriptRegex = true;
                        }
                    }
                } elseif ($char == '(' || $char == '=' || $char == ',' || $char == ';') {
                    $inSpecialScriptContext = true;
                } elseif (!$this->isSpaceChar($char)) {
                    $inSpecialScriptContext = false;
                }
            }
            $this->innerText .= $char;
            if ($inScriptString && $char != $scriptQuoteChar) {// $char != $scriptQuoteChar is used to filter out the first quote char from the string, otherwise the final string will include it and will look like this '#content
                $string .= $char;
            } else if ($string) {
                $this->strings[] = $string;
                $string = "";
            }
        }
    }

    public function getStrings() {
        return $this->strings;
    }

    public function replaceString($k, $newString) {
        $oldString = $this->strings[$k];
        $this->innerText = str_replace($oldString, $newString, $this->innerText);
        $this->strings[$k] = $newString;
    }
}
