/* vi:set ts=8 sts=4 sw=4 noet:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *			Visual Workshop integration by Gordon Prieur
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

#include "vim.h"

#if defined(FEAT_BEVAL) || defined(FEAT_PROP_POPUP) || defined(PROTO)
/*
 * Find text under the mouse position "row" / "col".
 * If "getword" is TRUE the returned text in "*textp" is not the whole line but
 * the relevant word in allocated memory.
 * Return OK if found.
 * Return FAIL if not found, no text at the mouse position.
 */
    int
find_word_under_cursor(
	int	    mouserow,
	int	    mousecol,
	int	    getword,
	int	    flags,	// flags for find_ident_at_pos()
	win_T	    **winp,	// can be NULL
	linenr_T    *lnump,	// can be NULL
	char_u	    **textp,
	int	    *colp,	// column where mouse hovers, can be NULL
	int	    *startcolp) // column where text starts, can be NULL
{
    int		row = mouserow;
    int		col = mousecol;
    int		scol;
    win_T	*wp;
    char_u	*lbuf;
    linenr_T	lnum;

    *textp = NULL;
    wp = mouse_find_win(&row, &col, FAIL_POPUP);
    if (wp != NULL && row >= 0 && row < wp->w_height && col < wp->w_width)
    {
	// Found a window and the cursor is in the text.  Now find the line
	// number.
	if (!mouse_comp_pos(wp, &row, &col, &lnum, NULL))
	{
	    // Not past end of the file.
	    lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
	    if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL))
	    {
		// Not past end of line.
		if (getword)
		{
		    // For Netbeans we get the relevant part of the line
		    // instead of the whole line.
		    int		len;
		    pos_T	*spos = NULL, *epos = NULL;

		    if (VIsual_active)
		    {
			if (LT_POS(VIsual, curwin->w_cursor))
			{
			    spos = &VIsual;
			    epos = &curwin->w_cursor;
			}
			else
			{
			    spos = &curwin->w_cursor;
			    epos = &VIsual;
			}
		    }

		    col = vcol2col(wp, lnum, col);
		    scol = col;

		    if (VIsual_active
			    && wp->w_buffer == curwin->w_buffer
			    && (lnum == spos->lnum
				? col >= (int)spos->col
				: lnum > spos->lnum)
			    && (lnum == epos->lnum
				? col <= (int)epos->col
				: lnum < epos->lnum))
		    {
			// Visual mode and pointing to the line with the
			// Visual selection: return selected text, with a
			// maximum of one line.
			if (spos->lnum != epos->lnum || spos->col == epos->col)
			    return FAIL;

			lbuf = ml_get_buf(curwin->w_buffer, VIsual.lnum, FALSE);
			len = epos->col - spos->col;
			if (*p_sel != 'e')
			    len += mb_ptr2len(lbuf + epos->col);
			lbuf = vim_strnsave(lbuf + spos->col, len);
			lnum = spos->lnum;
			col = spos->col;
			scol = col;
		    }
		    else
		    {
			// Find the word under the cursor.
			++emsg_off;
			len = find_ident_at_pos(wp, lnum, (colnr_T)col,
							  &lbuf, &scol, flags);
			--emsg_off;
			if (len == 0)
			    return FAIL;
			lbuf = vim_strnsave(lbuf, len);
		    }
		}

		if (winp != NULL)
		    *winp = wp;
		if (lnump != NULL)
		    *lnump = lnum;
		*textp = lbuf;
		if (colp != NULL)
		    *colp = col;
		if (startcolp != NULL)
		    *startcolp = scol;
		return OK;
	    }
	}
    }
    return FAIL;
}
#endif

#if defined(FEAT_BEVAL) || defined(PROTO)

/*
 * Get the text and position to be evaluated for "beval".
 * If "getword" is TRUE the returned text is not the whole line but the
 * relevant word in allocated memory.
 * Returns OK or FAIL.
 */
    int
get_beval_info(
	BalloonEval	*beval,
	int		getword,
	win_T		**winp,
	linenr_T	*lnump,
	char_u		**textp,
	int		*colp)
{
    int		row = mouse_row;
    int		col = mouse_col;

# ifdef FEAT_GUI
    if (gui.in_use)
    {
	row = Y_2_ROW(beval->y);
	col = X_2_COL(beval->x);
    }
#endif
    if (find_word_under_cursor(row, col, getword,
		FIND_IDENT + FIND_STRING + FIND_EVAL,
		winp, lnump, textp, colp, NULL) == OK)
    {
#ifdef FEAT_VARTABS
	vim_free(beval->vts);
	beval->vts = tabstop_copy((*winp)->w_buffer->b_p_vts_array);
	if ((*winp)->w_buffer->b_p_vts_array != NULL && beval->vts == NULL)
	{
	    if (getword)
		vim_free(*textp);
	    return FAIL;
	}
#endif
	beval->ts = (*winp)->w_buffer->b_p_ts;
	return OK;
    }

    return FAIL;
}

/*
 * Show a balloon with "mesg" or "list".
 * Hide the balloon when both are NULL.
 */
    void
post_balloon(BalloonEval *beval UNUSED, char_u *mesg, list_T *list UNUSED)
{
# ifdef FEAT_BEVAL_TERM
#  ifdef FEAT_GUI
    if (!gui.in_use)
#  endif
	ui_post_balloon(mesg, list);
# endif
# ifdef FEAT_BEVAL_GUI
    if (gui.in_use)
	// GUI can't handle a list
	gui_mch_post_balloon(beval, mesg);
# endif
}

/*
 * Returns TRUE if the balloon eval has been enabled:
 * 'ballooneval' for the GUI and 'balloonevalterm' for the terminal.
 * Also checks if the screen isn't scrolled up.
 */
    int
can_use_beval(void)
{
    return (0
#ifdef FEAT_BEVAL_GUI
		|| (gui.in_use && p_beval)
#endif
#ifdef FEAT_BEVAL_TERM
		|| (
# ifdef FEAT_GUI
		    !gui.in_use &&
# endif
		    p_bevalterm)
#endif
	     ) && msg_scrolled == 0;
}

/*
 * Common code, invoked when the mouse is resting for a moment.
 */
    void
general_beval_cb(BalloonEval *beval, int state UNUSED)
{
#ifdef FEAT_EVAL
    win_T	*wp;
    int		col;
    int		use_sandbox;
    linenr_T	lnum;
    char_u	*text;
    static char_u  *result = NULL;
    long	winnr = 0;
    char_u	*bexpr;
    buf_T	*save_curbuf;
    size_t	len;
    win_T	*cw;
#endif
    static int	recursive = FALSE;

    // Don't do anything when 'ballooneval' is off, messages scrolled the
    // windows up or we have no beval area.
    if (!can_use_beval() || beval == NULL)
	return;

    // Don't do this recursively.  Happens when the expression evaluation
    // takes a long time and invokes something that checks for CTRL-C typed.
    if (recursive)
	return;
    recursive = TRUE;

#ifdef FEAT_EVAL
    if (get_beval_info(beval, TRUE, &wp, &lnum, &text, &col) == OK)
    {
	bexpr = (*wp->w_buffer->b_p_bexpr == NUL) ? p_bexpr
						    : wp->w_buffer->b_p_bexpr;
	if (*bexpr != NUL)
	{
	    // Convert window pointer to number.
	    for (cw = firstwin; cw != wp; cw = cw->w_next)
		++winnr;

	    set_vim_var_nr(VV_BEVAL_BUFNR, (long)wp->w_buffer->b_fnum);
	    set_vim_var_nr(VV_BEVAL_WINNR, winnr);
	    set_vim_var_nr(VV_BEVAL_WINID, wp->w_id);
	    set_vim_var_nr(VV_BEVAL_LNUM, (long)lnum);
	    set_vim_var_nr(VV_BEVAL_COL, (long)(col + 1));
	    set_vim_var_string(VV_BEVAL_TEXT, text, -1);
	    vim_free(text);

	    /*
	     * Temporarily change the curbuf, so that we can determine whether
	     * the buffer-local balloonexpr option was set insecurely.
	     */
	    save_curbuf = curbuf;
	    curbuf = wp->w_buffer;
	    use_sandbox = was_set_insecurely((char_u *)"balloonexpr",
				 *curbuf->b_p_bexpr == NUL ? 0 : OPT_LOCAL);
	    curbuf = save_curbuf;
	    if (use_sandbox)
		++sandbox;
	    ++textlock;

	    vim_free(result);
	    result = eval_to_string(bexpr, NULL, TRUE);

	    // Remove one trailing newline, it is added when the result was a
	    // list and it's hardly ever useful.  If the user really wants a
	    // trailing newline he can add two and one remains.
	    if (result != NULL)
	    {
		len = STRLEN(result);
		if (len > 0 && result[len - 1] == NL)
		    result[len - 1] = NUL;
	    }

	    if (use_sandbox)
		--sandbox;
	    --textlock;

	    set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
	    if (result != NULL && result[0] != NUL)
		post_balloon(beval, result, NULL);

	    // The 'balloonexpr' evaluation may show something on the screen
	    // that requires a screen update.
	    if (must_redraw)
		redraw_after_callback(FALSE);

	    recursive = FALSE;
	    return;
	}
    }
#endif
#ifdef FEAT_NETBEANS_INTG
    if (bevalServers & BEVAL_NETBEANS)
	netbeans_beval_cb(beval, state);
#endif

    recursive = FALSE;
}

#endif
