<?php /*

 Composr
 Copyright (c) Christopher Graham, 2004-2024

 See docs/LICENSE.md for full licensing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license    http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright  Christopher Graham
 * @package    core
 */

/*EXTRA FUNCTIONS: Text_Diff.**/

/**
 * Standard code module initialisation function.
 *
 * @ignore
 */
function init__diff()
{
    require_code('diff/Diff');
    require_code('diff/Diff/Engine/native');
    require_code('diff/Diff/Engine/shell');
    require_code('diff/Diff/Engine/string');
    require_code('diff/Diff/Engine/xdiff');
    require_code('diff/Diff/Mapped');
    require_code('diff/Diff/Renderer');
    require_code('diff/Diff/Renderer/context');
    require_code('diff/Diff/Renderer/inline');
    require_code('diff/Diff/Renderer/unified');
}

/**
 * Create a diff between two strings.
 *
 * @param  string $old_contents First string
 * @param  string $new_contents Second string
 * @param  boolean $unified Whether to show a unified diff
 * @param  boolean $include_unchanged Whether to include unchanged lines and trailing whitespace
 * @return string Diff
 */
function diff_simple_text($old_contents, $new_contents, $unified = false, $include_unchanged = true)
{
    $before = ini_get('ocproducts.type_strictness');
    ini_set('ocproducts.type_strictness', '0');

    $ret = _diff_simple(($old_contents == '') ? array() : explode("\n", $old_contents), ($new_contents == '') ? array() : explode("\n", $new_contents), $unified, $include_unchanged);

    ini_set('ocproducts.type_strictness', $before);

    return $ret;
}

/**
 * Create a diff between two arrays of string-lines.
 *
 * @param  array $old First array
 * @param  array $new Second array
 * @param  boolean $unified Whether to show a unified diff
 * @param  boolean $include_unchanged Whether to include unchanged lines and trailing whitespace
 * @return string Diff
 * @ignore
 */
function _diff_simple($old, $new, $unified, $include_unchanged = true)
{
    $diff = new Text_Diff('auto', array($old, $new));
    if ($unified) {
        $renderer = new Text_Diff_Renderer_unified();
        $diff_text = $renderer->render($diff);
        $diff_html = '';
        foreach (explode("\n", $diff_text) as $diff_line) {
            switch (substr($diff_line, 0, 1)) {
                case '+':
                    $diff_html .= '<ins>' . escape_html($diff_line) . '</ins>';
                    break;
                case '-':
                    $diff_html .= '<del>' . escape_html($diff_line) . '</del>';
                    break;
                default:
                    if (!$include_unchanged) {
                        continue 2;
                    }
                    $diff_html .= escape_html($diff_line);
                    break;
            }
            $diff_html .= '<br />';
        }
    } else {
        $renderer = new Text_Diff_Renderer_inline();
        if (!$include_unchanged) {
            $renderer->_leading_context_lines = 0;
            $renderer->_trailing_context_lines = 0;
        }
        $diff_html = $renderer->render($diff);
        $diff_html = str_replace("\n", '<br />', $diff_html);
    }

    if (!$include_unchanged) {
        $diff_html = preg_replace('#(^|\n)[ \t]*(.*)#', '$1$2', $diff_html);
    }

    if ($GLOBALS['XSS_DETECT']) {
        ocp_mark_as_escaped($diff_html);
    }

    return $diff_html;
}

/**
 * Create a 3-way diff between three files.
 *
 * @param  PATH $text_1 First file contents
 * @param  PATH $text_2 Second file contents
 * @param  PATH $text_3 Third file contents (to apply diff between $text_1 and $text_2 to)
 * @return string New text
 */
function diff_3way_text($text_1, $text_2, $text_3)
{
    require_code('diff/Diff3');
    require_code('diff/Diff/ThreeWay');

    $before = ini_get('ocproducts.type_strictness');
    ini_set('ocproducts.type_strictness', '0');

    /* Load the lines of each file. */
    $lines_1 = explode("\n", $text_1);
    $lines_2 = explode("\n", $text_2);
    $lines_3 = explode("\n", $text_3);

    /* Create the Diff object. */
    $diff = new Text_Diff3($lines_1, $lines_2, $lines_3);
    //print_r($diff);
    //exit();
    //$renderer=new Text_Diff_Renderer_unified();
    //echo $renderer->render($diff);

    $new = '';
    foreach ($diff->_edits as $i => $ob) {
        if ($i != 0) {
            $new .= "\n";
        }

        $orig = implode("\n", $ob->orig);
        $final1 = implode("\n", $ob->final1);
        $final2 = implode("\n", $ob->final2);
        if (preg_replace('#\s#', '', $orig) != preg_replace('#\s#', '', $final1)) {
            $new .= $final1;
        } else {
            $new .= $final2;
        }
    }

    ini_set('ocproducts.type_strictness', $before);

    return $new;
}
