/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.inputmethod.pinyin;

import com.android.inputmethod.pinyin.PinyinIME.DecodingInfo;

import java.util.Vector;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * View to show candidate list. There two candidate view instances which are
 * used to show animation when user navigates between pages.
 */
public class CandidateView extends View {
    /**
     * The minimum width to show a item.
     */
    private static final float MIN_ITEM_WIDTH = 22;

    /**
     * Suspension points used to display long items.
     */
    private static final String SUSPENSION_POINTS = "...";

    /**
     * The width to draw candidates.
     */
    private int mContentWidth;

    /**
     * The height to draw candidate content.
     */
    private int mContentHeight;

    /**
     * Whether footnotes are displayed. Footnote is shown when hardware keyboard
     * is available.
     */
    private boolean mShowFootnote = true;

    /**
     * Balloon hint for candidate press/release.
     */
    private BalloonHint mBalloonHint;

    /**
     * Desired position of the balloon to the input view.
     */
    private int mHintPositionToInputView[] = new int[2];

    /**
     * Decoding result to show.
     */
    private DecodingInfo mDecInfo;

    /**
     * Listener used to notify IME that user clicks a candidate, or navigate
     * between them.
     */
    private CandidateViewListener mCvListener;

    /**
     * Used to notify the container to update the status of forward/backward
     * arrows.
     */
    private ArrowUpdater mArrowUpdater;

    /**
     * If true, update the arrow status when drawing candidates.
     */
    private boolean mUpdateArrowStatusWhenDraw = false;

    /**
     * Page number of the page displayed in this view.
     */
    private int mPageNo;

    /**
     * Active candidate position in this page.
     */
    private int mActiveCandInPage;

    /**
     * Used to decided whether the active candidate should be highlighted or
     * not. If user changes focus to composing view (The view to show Pinyin
     * string), the highlight in candidate view should be removed.
     */
    private boolean mEnableActiveHighlight = true;

    /**
     * The page which is just calculated.
     */
    private int mPageNoCalculated = -1;

    /**
     * The Drawable used to display as the background of the high-lighted item.
     */
    private Drawable mActiveCellDrawable;

    /**
     * The Drawable used to display as separators between candidates.
     */
    private Drawable mSeparatorDrawable;

    /**
     * Color to draw normal candidates generated by IME.
     */
    private int mImeCandidateColor;

    /**
     * Color to draw normal candidates Recommended by application.
     */
    private int mRecommendedCandidateColor;

    /**
     * Color to draw the normal(not highlighted) candidates, it can be one of
     * {@link #mImeCandidateColor} or {@link #mRecommendedCandidateColor}.
     */
    private int mNormalCandidateColor;

    /**
     * Color to draw the active(highlighted) candidates, including candidates
     * from IME and candidates from application.
     */
    private int mActiveCandidateColor;

    /**
     * Text size to draw candidates generated by IME.
     */
    private int mImeCandidateTextSize;

    /**
     * Text size to draw candidates recommended by application.
     */
    private int mRecommendedCandidateTextSize;

    /**
     * The current text size to draw candidates. It can be one of
     * {@link #mImeCandidateTextSize} or {@link #mRecommendedCandidateTextSize}.
     */
    private int mCandidateTextSize;

    /**
     * Paint used to draw candidates.
     */
    private Paint mCandidatesPaint;

    /**
     * Used to draw footnote.
     */
    private Paint mFootnotePaint;

    /**
     * The width to show suspension points.
     */
    private float mSuspensionPointsWidth;

    /**
     * Rectangle used to draw the active candidate.
     */
    private RectF mActiveCellRect;

    /**
     * Left and right margins for a candidate. It is specified in xml, and is
     * the minimum margin for a candidate. The actual gap between two candidates
     * is 2 * {@link #mCandidateMargin} + {@link #mSeparatorDrawable}.
     * getIntrinsicWidth(). Because length of candidate is not fixed, there can
     * be some extra space after the last candidate in the current page. In
     * order to achieve best look-and-feel, this extra space will be divided and
     * allocated to each candidates.
     */
    private float mCandidateMargin;

    /**
     * Left and right extra margins for a candidate.
     */
    private float mCandidateMarginExtra;

    /**
     * Rectangles for the candidates in this page.
     **/
    private Vector<RectF> mCandRects;

    /**
     * FontMetricsInt used to measure the size of candidates.
     */
    private FontMetricsInt mFmiCandidates;

    /**
     * FontMetricsInt used to measure the size of footnotes.
     */
    private FontMetricsInt mFmiFootnote;

    private PressTimer mTimer = new PressTimer();

    private GestureDetector mGestureDetector;

    private int mLocationTmp[] = new int[2];

    public CandidateView(Context context, AttributeSet attrs) {
        super(context, attrs);

        Resources r = context.getResources();

        Configuration conf = r.getConfiguration();
        if (conf.keyboard == Configuration.KEYBOARD_NOKEYS
                || conf.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
            mShowFootnote = false;
        }

        mActiveCellDrawable = r.getDrawable(R.drawable.candidate_hl_bg);
        mSeparatorDrawable = r.getDrawable(R.drawable.candidates_vertical_line);
        mCandidateMargin = r.getDimension(R.dimen.candidate_margin_left_right);

        mImeCandidateColor = r.getColor(R.color.candidate_color);
        mRecommendedCandidateColor = r.getColor(R.color.recommended_candidate_color);
        mNormalCandidateColor = mImeCandidateColor;
        mActiveCandidateColor = r.getColor(R.color.active_candidate_color);

        mCandidatesPaint = new Paint();
        mCandidatesPaint.setAntiAlias(true);

        mFootnotePaint = new Paint();
        mFootnotePaint.setAntiAlias(true);
        mFootnotePaint.setColor(r.getColor(R.color.footnote_color));
        mActiveCellRect = new RectF();

        mCandRects = new Vector<RectF>();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int mOldWidth = getMeasuredWidth();
        int mOldHeight = getMeasuredHeight();

        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(),
                widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(),
                heightMeasureSpec));

        if (mOldWidth != getMeasuredWidth() || mOldHeight != getMeasuredHeight()) {
            onSizeChanged();
        }
    }

    public void initialize(ArrowUpdater arrowUpdater, BalloonHint balloonHint,
            GestureDetector gestureDetector, CandidateViewListener cvListener) {
        mArrowUpdater = arrowUpdater;
        mBalloonHint = balloonHint;
        mGestureDetector = gestureDetector;
        mCvListener = cvListener;
    }

    public void setDecodingInfo(DecodingInfo decInfo) {
        if (null == decInfo) return;
        mDecInfo = decInfo;
        mPageNoCalculated = -1;

        if (mDecInfo.candidatesFromApp()) {
            mNormalCandidateColor = mRecommendedCandidateColor;
            mCandidateTextSize = mRecommendedCandidateTextSize;
        } else {
            mNormalCandidateColor = mImeCandidateColor;
            mCandidateTextSize = mImeCandidateTextSize;
        }
        if (mCandidatesPaint.getTextSize() != mCandidateTextSize) {
            mCandidatesPaint.setTextSize(mCandidateTextSize);
            mFmiCandidates = mCandidatesPaint.getFontMetricsInt();
            mSuspensionPointsWidth =
                    mCandidatesPaint.measureText(SUSPENSION_POINTS);
        }

        // Remove any pending timer for the previous list.
        mTimer.removeTimer();
    }

    public int getActiveCandiatePosInPage() {
        return mActiveCandInPage;
    }

    public int getActiveCandiatePosGlobal() {
        return mDecInfo.mPageStart.get(mPageNo) + mActiveCandInPage;
    }

    /**
     * Show a page in the decoding result set previously.
     *
     * @param pageNo Which page to show.
     * @param activeCandInPage Which candidate should be set as active item.
     * @param enableActiveHighlight When false, active item will not be
     *        highlighted.
     */
    public void showPage(int pageNo, int activeCandInPage,
            boolean enableActiveHighlight) {
        if (null == mDecInfo) return;
        mPageNo = pageNo;
        mActiveCandInPage = activeCandInPage;
        if (mEnableActiveHighlight != enableActiveHighlight) {
            mEnableActiveHighlight = enableActiveHighlight;
        }

        if (!calculatePage(mPageNo)) {
            mUpdateArrowStatusWhenDraw = true;
        } else {
            mUpdateArrowStatusWhenDraw = false;
        }

        invalidate();
    }

    public void enableActiveHighlight(boolean enableActiveHighlight) {
        if (enableActiveHighlight == mEnableActiveHighlight) return;

        mEnableActiveHighlight = enableActiveHighlight;
        invalidate();
    }

    public boolean activeCursorForward() {
        if (!mDecInfo.pageReady(mPageNo)) return false;
        int pageSize = mDecInfo.mPageStart.get(mPageNo + 1)
                - mDecInfo.mPageStart.get(mPageNo);
        if (mActiveCandInPage + 1 < pageSize) {
            showPage(mPageNo, mActiveCandInPage + 1, true);
            return true;
        }
        return false;
    }

    public boolean activeCurseBackward() {
        if (mActiveCandInPage > 0) {
            showPage(mPageNo, mActiveCandInPage - 1, true);
            return true;
        }
        return false;
    }

    private void onSizeChanged() {
        mContentWidth = getMeasuredWidth() - mPaddingLeft - mPaddingRight;
        mContentHeight = (int) ((getMeasuredHeight() - mPaddingTop - mPaddingBottom) * 0.95f);
        /**
         * How to decide the font size if the height for display is given?
         * Now it is implemented in a stupid way.
         */
        int textSize = 1;
        mCandidatesPaint.setTextSize(textSize);
        mFmiCandidates = mCandidatesPaint.getFontMetricsInt();
        while (mFmiCandidates.bottom - mFmiCandidates.top < mContentHeight) {
            textSize++;
            mCandidatesPaint.setTextSize(textSize);
            mFmiCandidates = mCandidatesPaint.getFontMetricsInt();
        }

        mImeCandidateTextSize = textSize;
        mRecommendedCandidateTextSize = textSize * 3 / 4;
        if (null == mDecInfo) {
            mCandidateTextSize = mImeCandidateTextSize;
            mCandidatesPaint.setTextSize(mCandidateTextSize);
            mFmiCandidates = mCandidatesPaint.getFontMetricsInt();
            mSuspensionPointsWidth =
                mCandidatesPaint.measureText(SUSPENSION_POINTS);
        } else {
            // Reset the decoding information to update members for painting.
            setDecodingInfo(mDecInfo);
        }

        textSize = 1;
        mFootnotePaint.setTextSize(textSize);
        mFmiFootnote = mFootnotePaint.getFontMetricsInt();
        while (mFmiFootnote.bottom - mFmiFootnote.top < mContentHeight / 2) {
            textSize++;
            mFootnotePaint.setTextSize(textSize);
            mFmiFootnote = mFootnotePaint.getFontMetricsInt();
        }
        textSize--;
        mFootnotePaint.setTextSize(textSize);
        mFmiFootnote = mFootnotePaint.getFontMetricsInt();

        // When the size is changed, the first page will be displayed.
        mPageNo = 0;
        mActiveCandInPage = 0;
    }

    private boolean calculatePage(int pageNo) {
        if (pageNo == mPageNoCalculated) return true;

        mContentWidth = getMeasuredWidth() - mPaddingLeft - mPaddingRight;
        mContentHeight = (int) ((getMeasuredHeight() - mPaddingTop - mPaddingBottom) * 0.95f);

        if (mContentWidth <= 0 || mContentHeight <= 0) return false;

        int candSize = mDecInfo.mCandidatesList.size();

        // If the size of page exists, only calculate the extra margin.
        boolean onlyExtraMargin = false;
        int fromPage = mDecInfo.mPageStart.size() - 1;
        if (mDecInfo.mPageStart.size() > pageNo + 1) {
            onlyExtraMargin = true;
            fromPage = pageNo;
        }

        // If the previous pages have no information, calculate them first.
        for (int p = fromPage; p <= pageNo; p++) {
            int pStart = mDecInfo.mPageStart.get(p);
            int pSize = 0;
            int charNum = 0;
            float lastItemWidth = 0;

            float xPos;
            xPos = 0;
            xPos += mSeparatorDrawable.getIntrinsicWidth();
            while (xPos < mContentWidth && pStart + pSize < candSize) {
                int itemPos = pStart + pSize;
                String itemStr = mDecInfo.mCandidatesList.get(itemPos);
                float itemWidth = mCandidatesPaint.measureText(itemStr);
                if (itemWidth < MIN_ITEM_WIDTH) itemWidth = MIN_ITEM_WIDTH;

                itemWidth += mCandidateMargin * 2;
                itemWidth += mSeparatorDrawable.getIntrinsicWidth();
                if (xPos + itemWidth < mContentWidth || 0 == pSize) {
                    xPos += itemWidth;
                    lastItemWidth = itemWidth;
                    pSize++;
                    charNum += itemStr.length();
                } else {
                    break;
                }
            }
            if (!onlyExtraMargin) {
                mDecInfo.mPageStart.add(pStart + pSize);
                mDecInfo.mCnToPage.add(mDecInfo.mCnToPage.get(p) + charNum);
            }

            float marginExtra = (mContentWidth - xPos) / pSize / 2;

            if (mContentWidth - xPos > lastItemWidth) {
                // Must be the last page, because if there are more items,
                // the next item's width must be less than lastItemWidth.
                // In this case, if the last margin is less than the current
                // one, the last margin can be used, so that the
                // look-and-feeling will be the same as the previous page.
                if (mCandidateMarginExtra <= marginExtra) {
                    marginExtra = mCandidateMarginExtra;
                }
            } else if (pSize == 1) {
                marginExtra = 0;
            }
            mCandidateMarginExtra = marginExtra;
        }
        mPageNoCalculated = pageNo;
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // The invisible candidate view(the one which is not in foreground) can
        // also be called to drawn, but its decoding result and candidate list
        // may be empty.
        if (null == mDecInfo || mDecInfo.isCandidatesListEmpty()) return;

        // Calculate page. If the paging information is ready, the function will
        // return at once.
        calculatePage(mPageNo);

        int pStart = mDecInfo.mPageStart.get(mPageNo);
        int pSize = mDecInfo.mPageStart.get(mPageNo + 1) - pStart;
        float candMargin = mCandidateMargin + mCandidateMarginExtra;
        if (mActiveCandInPage > pSize - 1) {
            mActiveCandInPage = pSize - 1;
        }

        mCandRects.removeAllElements();

        float xPos = mPaddingLeft;
        int yPos = (getMeasuredHeight() -
                (mFmiCandidates.bottom - mFmiCandidates.top)) / 2
                - mFmiCandidates.top;
        xPos += drawVerticalSeparator(canvas, xPos);
        for (int i = 0; i < pSize; i++) {
            float footnoteSize = 0;
            String footnote = null;
            if (mShowFootnote) {
                footnote = Integer.toString(i + 1);
                footnoteSize = mFootnotePaint.measureText(footnote);
                assert (footnoteSize < candMargin);
            }
            String cand = mDecInfo.mCandidatesList.get(pStart + i);
            float candidateWidth = mCandidatesPaint.measureText(cand);
            float centerOffset = 0;
            if (candidateWidth < MIN_ITEM_WIDTH) {
                centerOffset = (MIN_ITEM_WIDTH - candidateWidth) / 2;
                candidateWidth = MIN_ITEM_WIDTH;
            }

            float itemTotalWidth = candidateWidth + 2 * candMargin;

            if (mActiveCandInPage == i && mEnableActiveHighlight) {
                mActiveCellRect.set(xPos, mPaddingTop + 1, xPos
                        + itemTotalWidth, getHeight() - mPaddingBottom - 1);
                mActiveCellDrawable.setBounds((int) mActiveCellRect.left,
                        (int) mActiveCellRect.top, (int) mActiveCellRect.right,
                        (int) mActiveCellRect.bottom);
                mActiveCellDrawable.draw(canvas);
            }

            if (mCandRects.size() < pSize) mCandRects.add(new RectF());
            mCandRects.elementAt(i).set(xPos - 1, yPos + mFmiCandidates.top,
                    xPos + itemTotalWidth + 1, yPos + mFmiCandidates.bottom);

            // Draw footnote
            if (mShowFootnote) {
                canvas.drawText(footnote, xPos + (candMargin - footnoteSize)
                        / 2, yPos, mFootnotePaint);
            }

            // Left margin
            xPos += candMargin;
            if (candidateWidth > mContentWidth - xPos - centerOffset) {
                cand = getLimitedCandidateForDrawing(cand,
                        mContentWidth - xPos - centerOffset);
            }
            if (mActiveCandInPage == i && mEnableActiveHighlight) {
                mCandidatesPaint.setColor(mActiveCandidateColor);
            } else {
                mCandidatesPaint.setColor(mNormalCandidateColor);
            }
            canvas.drawText(cand, xPos + centerOffset, yPos,
                    mCandidatesPaint);

            // Candidate and right margin
            xPos += candidateWidth + candMargin;

            // Draw the separator between candidates.
            xPos += drawVerticalSeparator(canvas, xPos);
        }

        // Update the arrow status of the container.
        if (null != mArrowUpdater && mUpdateArrowStatusWhenDraw) {
            mArrowUpdater.updateArrowStatus();
            mUpdateArrowStatusWhenDraw = false;
        }
    }

    private String getLimitedCandidateForDrawing(String rawCandidate,
            float widthToDraw) {
        int subLen = rawCandidate.length();
        if (subLen <= 1) return rawCandidate;
        do {
            subLen--;
            float width = mCandidatesPaint.measureText(rawCandidate, 0, subLen);
            if (width + mSuspensionPointsWidth <= widthToDraw || 1 >= subLen) {
                return rawCandidate.substring(0, subLen) +
                        SUSPENSION_POINTS;
            }
        } while (true);
    }

    private float drawVerticalSeparator(Canvas canvas, float xPos) {
        mSeparatorDrawable.setBounds((int) xPos, mPaddingTop, (int) xPos
                + mSeparatorDrawable.getIntrinsicWidth(), getMeasuredHeight()
                - mPaddingBottom);
        mSeparatorDrawable.draw(canvas);
        return mSeparatorDrawable.getIntrinsicWidth();
    }

    private int mapToItemInPage(int x, int y) {
        // mCandRects.size() == 0 happens when the page is set, but
        // touch events occur before onDraw(). It usually happens with
        // monkey test.
        if (!mDecInfo.pageReady(mPageNo) || mPageNoCalculated != mPageNo
                || mCandRects.size() == 0) {
            return -1;
        }

        int pageStart = mDecInfo.mPageStart.get(mPageNo);
        int pageSize = mDecInfo.mPageStart.get(mPageNo + 1) - pageStart;
        if (mCandRects.size() < pageSize) {
            return -1;
        }

        // If not found, try to find the nearest one.
        float nearestDis = Float.MAX_VALUE;
        int nearest = -1;
        for (int i = 0; i < pageSize; i++) {
            RectF r = mCandRects.elementAt(i);
            if (r.left < x && r.right > x && r.top < y && r.bottom > y) {
                return i;
            }
            float disx = (r.left + r.right) / 2 - x;
            float disy = (r.top + r.bottom) / 2 - y;
            float dis = disx * disx + disy * disy;
            if (dis < nearestDis) {
                nearestDis = dis;
                nearest = i;
            }
        }

        return nearest;
    }

    // Because the candidate view under the current focused one may also get
    // touching events. Here we just bypass the event to the container and let
    // it decide which view should handle the event.
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }

    public boolean onTouchEventReal(MotionEvent event) {
        // The page in the background can also be touched.
        if (null == mDecInfo || !mDecInfo.pageReady(mPageNo)
                || mPageNoCalculated != mPageNo) return true;

        int x, y;
        x = (int) event.getX();
        y = (int) event.getY();

        if (mGestureDetector.onTouchEvent(event)) {
            mTimer.removeTimer();
            mBalloonHint.delayedDismiss(0);
            return true;
        }

        int clickedItemInPage = -1;

        switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            clickedItemInPage = mapToItemInPage(x, y);
            if (clickedItemInPage >= 0) {
                invalidate();
                mCvListener.onClickChoice(clickedItemInPage
                        + mDecInfo.mPageStart.get(mPageNo));
            }
            mBalloonHint.delayedDismiss(BalloonHint.TIME_DELAY_DISMISS);
            break;

        case MotionEvent.ACTION_DOWN:
            clickedItemInPage = mapToItemInPage(x, y);
            if (clickedItemInPage >= 0) {
                showBalloon(clickedItemInPage, true);
                mTimer.startTimer(BalloonHint.TIME_DELAY_SHOW, mPageNo,
                        clickedItemInPage);
            }
            break;

        case MotionEvent.ACTION_CANCEL:
            break;

        case MotionEvent.ACTION_MOVE:
            clickedItemInPage = mapToItemInPage(x, y);
            if (clickedItemInPage >= 0
                    && (clickedItemInPage != mTimer.getActiveCandOfPageToShow() || mPageNo != mTimer
                            .getPageToShow())) {
                showBalloon(clickedItemInPage, true);
                mTimer.startTimer(BalloonHint.TIME_DELAY_SHOW, mPageNo,
                        clickedItemInPage);
            }
        }
        return true;
    }

    private void showBalloon(int candPos, boolean delayedShow) {
        mBalloonHint.removeTimer();

        RectF r = mCandRects.elementAt(candPos);
        int desired_width = (int) (r.right - r.left);
        int desired_height = (int) (r.bottom - r.top);
        mBalloonHint.setBalloonConfig(mDecInfo.mCandidatesList
                .get(mDecInfo.mPageStart.get(mPageNo) + candPos), 44, true,
                mImeCandidateColor, desired_width, desired_height);

        getLocationOnScreen(mLocationTmp);
        mHintPositionToInputView[0] = mLocationTmp[0]
                + (int) (r.left - (mBalloonHint.getWidth() - desired_width) / 2);
        mHintPositionToInputView[1] = -mBalloonHint.getHeight();

        long delay = BalloonHint.TIME_DELAY_SHOW;
        if (!delayedShow) delay = 0;
        mBalloonHint.dismiss();
        if (!mBalloonHint.isShowing()) {
            mBalloonHint.delayedShow(delay, mHintPositionToInputView);
        } else {
            mBalloonHint.delayedUpdate(0, mHintPositionToInputView, -1, -1);
        }
    }

    private class PressTimer extends Handler implements Runnable {
        private boolean mTimerPending = false;
        private int mPageNoToShow;
        private int mActiveCandOfPage;

        public PressTimer() {
            super();
        }

        public void startTimer(long afterMillis, int pageNo, int activeInPage) {
            mTimer.removeTimer();
            postDelayed(this, afterMillis);
            mTimerPending = true;
            mPageNoToShow = pageNo;
            mActiveCandOfPage = activeInPage;
        }

        public int getPageToShow() {
            return mPageNoToShow;
        }

        public int getActiveCandOfPageToShow() {
            return mActiveCandOfPage;
        }

        public boolean removeTimer() {
            if (mTimerPending) {
                mTimerPending = false;
                removeCallbacks(this);
                return true;
            }
            return false;
        }

        public boolean isPending() {
            return mTimerPending;
        }

        public void run() {
            if (mPageNoToShow >= 0 && mActiveCandOfPage >= 0) {
                // Always enable to highlight the clicked one.
                showPage(mPageNoToShow, mActiveCandOfPage, true);
                invalidate();
            }
            mTimerPending = false;
        }
    }
}
