/* deflate_slow.c -- compress data using the slow strategy of deflation algorithm
 *
 * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
 * For conditions of distribution and use, see copyright notice in zlib.h
 */

#include "zbuild.h"
#include "deflate.h"
#include "deflate_p.h"
#include "functable.h"

/* ===========================================================================
 * Same as deflate_medium, but achieves better compression. We use a lazy
 * evaluation for matches: a match is finally adopted only if there is
 * no better match at the next window position.
 */
Z_INTERNAL block_state deflate_slow(deflate_state *s, int flush) {
    Pos hash_head;           /* head of hash chain */
    int bflush;              /* set if current block must be flushed */
    int64_t dist;
    uint32_t match_len;
    match_func *longest_match;

    if (s->max_chain_length <= 1024)
        longest_match = &functable.longest_match;
    else
        longest_match = &functable.longest_match_slow;

    /* Process the input block. */
    for (;;) {
        /* Make sure that we always have enough lookahead, except
         * at the end of the input file. We need STD_MAX_MATCH bytes
         * for the next match, plus WANT_MIN_MATCH bytes to insert the
         * string following the next match.
         */
        if (s->lookahead < MIN_LOOKAHEAD) {
            PREFIX(fill_window)(s);
            if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) {
                return need_more;
            }
            if (UNLIKELY(s->lookahead == 0))
                break; /* flush the current block */
        }

        /* Insert the string window[strstart .. strstart+2] in the
         * dictionary, and set hash_head to the head of the hash chain:
         */
        hash_head = 0;
        if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) {
            hash_head = s->quick_insert_string(s, s->strstart);
        }

        /* Find the longest match, discarding those <= prev_length.
         */
        s->prev_match = (Pos)s->match_start;
        match_len = STD_MIN_MATCH - 1;
        dist = (int64_t)s->strstart - hash_head;

        if (dist <= MAX_DIST(s) && dist > 0 && s->prev_length < s->max_lazy_match && hash_head != 0) {
            /* To simplify the code, we prevent matches with the string
             * of window index 0 (in particular we have to avoid a match
             * of the string with itself at the start of the input file).
             */
            match_len = (*longest_match)(s, hash_head);
            /* longest_match() sets match_start */

            if (match_len <= 5 && (s->strategy == Z_FILTERED)) {
                /* If prev_match is also WANT_MIN_MATCH, match_start is garbage
                 * but we will ignore the current match anyway.
                 */
                match_len = STD_MIN_MATCH - 1;
            }
        }
        /* If there was a match at the previous step and the current
         * match is not better, output the previous match:
         */
        if (s->prev_length >= STD_MIN_MATCH && match_len <= s->prev_length) {
            unsigned int max_insert = s->strstart + s->lookahead - STD_MIN_MATCH;
            /* Do not insert strings in hash table beyond this. */

            check_match(s, s->strstart-1, s->prev_match, s->prev_length);

            bflush = zng_tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - STD_MIN_MATCH);

            /* Insert in hash table all strings up to the end of the match.
             * strstart-1 and strstart are already inserted. If there is not
             * enough lookahead, the last two strings are not inserted in
             * the hash table.
             */
            s->prev_length -= 1;
            s->lookahead -= s->prev_length;

            unsigned int mov_fwd = s->prev_length - 1;
            if (max_insert > s->strstart) {
                unsigned int insert_cnt = mov_fwd;
                if (UNLIKELY(insert_cnt > max_insert - s->strstart))
                    insert_cnt = max_insert - s->strstart;
                s->insert_string(s, s->strstart + 1, insert_cnt);
            }
            s->prev_length = 0;
            s->match_available = 0;
            s->strstart += mov_fwd + 1;

            if (UNLIKELY(bflush))
                FLUSH_BLOCK(s, 0);

        } else if (s->match_available) {
            /* If there was no match at the previous position, output a
             * single literal. If there was a match but the current match
             * is longer, truncate the previous match to a single literal.
             */
            bflush = zng_tr_tally_lit(s, s->window[s->strstart-1]);
            if (UNLIKELY(bflush))
                FLUSH_BLOCK_ONLY(s, 0);
            s->prev_length = match_len;
            s->strstart++;
            s->lookahead--;
            if (UNLIKELY(s->strm->avail_out == 0))
                return need_more;
        } else {
            /* There is no previous match to compare with, wait for
             * the next step to decide.
             */
            s->prev_length = match_len;
            s->match_available = 1;
            s->strstart++;
            s->lookahead--;
        }
    }
    Assert(flush != Z_NO_FLUSH, "no flush?");
    if (UNLIKELY(s->match_available)) {
        (void) zng_tr_tally_lit(s, s->window[s->strstart-1]);
        s->match_available = 0;
    }
    s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1);
    if (UNLIKELY(flush == Z_FINISH)) {
        FLUSH_BLOCK(s, 1);
        return finish_done;
    }
    if (UNLIKELY(s->sym_next))
        FLUSH_BLOCK(s, 0);
    return block_done;
}
