import _ from 'lodash';
import '../../assert/js/assert.js';
import '../../tandem/js/PhetioIDUtils.js';
import '../../globals.js';
import Vector2 from '../../dot/js/Vector2.js';
import { Shape } from '../../kite/js/imports.js';
import optionize from '../../phet-core/js/optionize.js';
import { Circle, FlowBox, LayoutOrientationValues, Node, PressListener } from '../../scenery/js/imports.js';
import Tandem from '../../tandem/js/Tandem.js';
import sun from './sun.js';
export default class PageControl extends Node {
    /**
     * @param pageNumberProperty - which page is currently visible
     * @param numberOfPagesProperty - number of pages
     * @param providedOptions
     */
    constructor(pageNumberProperty, numberOfPagesProperty, providedOptions) {
        const options = optionize()({
            // SelfOptions
            interactive: false,
            orientation: 'horizontal',
            dotRadius: 3,
            lineWidth: 1,
            dotSpacing: 10,
            dotTouchAreaDilation: 4,
            dotMouseAreaDilation: 4,
            currentPageFill: 'black',
            currentPageStroke: null,
            pageFill: 'rgb( 200, 200, 200 )',
            pageStroke: null,
            // NodeOptions
            tandem: Tandem.REQUIRED,
            tandemNameSuffix: 'PageControl',
            visiblePropertyOptions: {
                phetioFeatured: true
            }
        }, providedOptions);
        // validate options
        assert && assert(LayoutOrientationValues.includes(options.orientation), `invalid orientation=${options.orientation}`);
        // Clicking on a dot goes to that page
        const pressListener = new PressListener({
            press: (event) => {
                if (event.currentTarget instanceof DotNode) {
                    pageNumberProperty.value = event.currentTarget.pageNumber;
                }
            },
            tandem: options.tandem.createTandem('pressListener')
        });
        const dotOptions = {
            lineWidth: options.lineWidth,
            mouseArea: (options.dotMouseAreaDilation === 0) ? null : Shape.circle(0, 0, options.dotRadius + options.dotMouseAreaDilation),
            touchArea: (options.dotTouchAreaDilation === 0) ? null : Shape.circle(0, 0, options.dotRadius + options.dotTouchAreaDilation),
            boundsMethod: 'unstroked', // For layout purposes, so we don't have to adjust spacings when things become stroked
            // optional interactivity
            cursor: options.interactive ? 'pointer' : null,
            inputListeners: options.interactive ? [pressListener] : []
        };
        const dotBox = new FlowBox({
            orientation: options.orientation, // horizontal pages ordered left-to-right, vertical pages ordered top-to-bottom
            spacing: options.dotSpacing
        });
        let dotNodes = [];
        // Keep it centered
        dotBox.boundsProperty.link(() => { dotBox.center = Vector2.ZERO; });
        // Dot fill/stroke
        const updateDotAppearance = (pageNumber) => {
            dotNodes.forEach(dotNode => {
                dotNode.fill = (pageNumber === dotNode.pageNumber) ? options.currentPageFill : options.pageFill;
                dotNode.stroke = (pageNumber === dotNode.pageNumber) ? options.currentPageStroke : options.pageStroke;
            });
        };
        pageNumberProperty.link(updateDotAppearance);
        // Recreate the dots when the number of pages changes
        const recreateDotNodes = (numberOfPages) => {
            assert && assert(numberOfPages >= 1);
            dotNodes = _.range(0, numberOfPages).map(pageNumber => new DotNode(pageNumber, options.dotRadius, dotOptions));
            dotBox.children = dotNodes;
            updateDotAppearance(pageNumberProperty.value); // since they are recreated, update their appearance
        };
        numberOfPagesProperty.link(recreateDotNodes);
        options.children = [dotBox];
        super(options);
        this.disposePageControl = () => {
            pressListener.dispose();
            numberOfPagesProperty.unlink(recreateDotNodes);
            pageNumberProperty.unlink(updateDotAppearance);
        };
    }
    dispose() {
        this.disposePageControl();
        super.dispose();
    }
}
/**
 * One of the dots in the page control, with an associated page number.
 */
class DotNode extends Circle {
    constructor(pageNumber, radius, options) {
        super(radius, options);
        this.pageNumber = pageNumber;
    }
}
sun.register('PageControl', PageControl);
//# sourceMappingURL=PageControl.js.map