/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.wicket.examples.linkomatic;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import org.apache.wicket.Component;
import org.apache.wicket.examples.WicketExamplePage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ClientSideImageMap;
import org.apache.wicket.markup.html.link.DownloadLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.link.PopupSettings;
import org.apache.wicket.markup.html.link.ResourceLink;
import org.apache.wicket.markup.html.pages.RedirectPage;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.parser.filter.RelativePathPrefixHandler;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.resource.PackageResourceReference;
import org.apache.wicket.request.resource.SharedResourceReference;
import org.apache.wicket.util.file.Files;


/**
 * Demonstrates different flavors of hyperlinks.
 * 
 * @author Jonathan Locke
 */
public class Home extends WicketExamplePage
{
    /** click count for Link. */
    private int linkClickCount = 0;

    /** click count for OnClickLink. */
    private int onClickLinkClickCount = 0;

    /**
     * Constructor
     */
    public Home()
    {
        // Action link counts link clicks
        final Link<Void> actionLink = new Link<Void>("actionLink")
        {
            public void onClick()
            {
                linkClickCount++;
            }
        };
        actionLink
            .add(new Label("linkClickCount", new PropertyModel<Integer>(this, "linkClickCount")));
        add(actionLink);

        // Action link counts link clicks on works with onclick handler
        final Link<Void> actionOnClickLink = new Link<Void>("actionOnClickLink")
        {
            public void onClick()
            {
                onClickLinkClickCount++;
            }
        };
        add(actionOnClickLink);
        add(new Label("onClickLinkClickCount",
            new PropertyModel<Integer>(this, "onClickLinkClickCount")));

        // Link to Page1 is a simple external page link
        add(new BookmarkablePageLink<>("page1Link", Page1.class));

        // Link to Page2 is automaticLink, so no code
        // Link to Page3 is an external link which takes a parameter
        BookmarkablePageLink<Void> page3Link = new BookmarkablePageLink<>("page3Link", Page3.class);
        page3Link.getPageParameters().add("bookmarkparameter", "3++2 & 5 � >< space + �");
        add(page3Link);

        // Link to BookDetails page
        add(new Link<Void>("bookDetailsLink")
        {
            public void onClick()
            {
                setResponsePage(new BookDetails(new Book("The Hobbit")));
            }
        });

        // Delayed link to BookDetails page
        add(new Link<Void>("bookDetailsLink2")
        {
            public void onClick()
            {
                setResponsePage(new BookDetails(new Book("Inside The Matrix")));
            }
        });

        // Image map link example
        Image imageForMap = new Image("imageForMap",
            new PackageResourceReference(Home.class, "ImageMap.gif"));
        add(imageForMap);
        add(new ClientSideImageMap("imageMap", imageForMap)
            .addRectangleArea(new BookmarkablePageLink<Page1>("page1", Page1.class), 0, 0, 100, 100)
            .addCircleArea(new BookmarkablePageLink<Page2>("page2", Page2.class), 160, 50, 35)
            .addPolygonArea(new BookmarkablePageLink<Page3>("page3", Page3.class), 212, 79, 241, 4,
                279, 54, 212, 79)
            .add(RelativePathPrefixHandler.RELATIVE_PATH_BEHAVIOR));

        // Popup example
        PopupSettings popupSettings = new PopupSettings("popuppagemap").setHeight(500)
            .setWidth(500);
        add(new BookmarkablePageLink<>("popupLink", Popup.class).setPopupSettings(popupSettings));

        // Popup example
        add(new BookmarkablePageLink<>("popupButtonLink", Popup.class)
            .setPopupSettings(popupSettings));

        // External site link
        add(new ExternalLink("google", "http://www.google.com", "Click this link to go to Google"));

        // And that link as a popup
        PopupSettings googlePopupSettings = new PopupSettings(
            PopupSettings.RESIZABLE | PopupSettings.SCROLLBARS).setHeight(500).setWidth(700);
        add(new ExternalLink("googlePopup", "http://www.google.com",
            "Click this link to go to Google in a popup").setPopupSettings(googlePopupSettings));

        // Shared resource link
        add(new ResourceLink<>("cancelButtonLink", new SharedResourceReference("cancelButton")));

        add(new DownloadLink("downloadLink", new IModel<File>()
        {
            private static final long serialVersionUID = 1L;

            @Override
            public File getObject()
            {
                File tempFile;
                try
                {
                    tempFile = File.createTempFile("wicket-examples-download-link--", ".tmp");

                    InputStream data = new ByteArrayInputStream("some data".getBytes());
                    Files.writeTo(tempFile, data);

                }
                catch (IOException e)
                {
                    throw new RuntimeException(e);
                }

                return tempFile;
            }
        }, "Downlöad\"here now.tmp").setCacheDuration(Duration.ZERO).setDeleteAfterDownload(true));

        // redirect to external url form
        FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
        add(feedbackPanel);
        add(new RedirectForm("redirectForm"));

        Link<Void> linkToAnchor = new Link<Void>("linkToAnchor")
        {
            @Override
            public void onClick()
            {
            }
        };
        add(linkToAnchor);
        Link<Void> anotherlinkToAnchor = new Link<Void>("anotherlinkToAnchor")
        {
            @Override
            public void onClick()
            {
            };
        };
        add(anotherlinkToAnchor);
        Component anchorLabel = new Label("anchorLabel",
            "this label is here to function as an anchor for a link").setOutputMarkupId(true);
        add(anchorLabel);
        linkToAnchor.setAnchor(anchorLabel);

        Link<Void> linkWithLabel = new Link<Void>("linkWithLabel")
        {
            @Override
            public void onClick()
            {
            }
        };
        linkWithLabel
            .setBody(Model.of("A link that provides its body with Link.setBody(someModel)"));
        add(linkWithLabel);
    }

    /**
     * Form that handles a redirect.
     */
    private final class RedirectForm extends Form<RedirectForm>
    {
        /** receives form input. */
        private String redirectUrl = "http://www.theserverside.com";

        /**
         * Construct.
         * 
         * @param id
         *            component id
         */
        public RedirectForm(String id)
        {
            super(id);
            setDefaultModel(new CompoundPropertyModel<>(this));
            add(new TextField<>("redirectUrl"));
        }

        @Override
        protected void onSubmit()
        {
            setResponsePage(new RedirectPage(redirectUrl));
        }

        /**
         * Gets the redirectUrl.
         * 
         * @return redirectUrl
         */
        public String getRedirectUrl()
        {
            return redirectUrl;
        }

        /**
         * Sets the redirectUrl.
         * 
         * @param redirectUrl
         *            redirectUrl
         */
        public void setRedirectUrl(String redirectUrl)
        {
            this.redirectUrl = redirectUrl;
        }
    }

    /**
     * @return Returns the linkClickCount.
     */
    public int getLinkClickCount()
    {
        return linkClickCount;
    }

    /**
     * @param linkClickCount
     *            The linkClickCount to set.
     */
    public void setLinkClickCount(final int linkClickCount)
    {
        this.linkClickCount = linkClickCount;
    }

    /**
     * Gets onClickLinkClickCount.
     * 
     * @return onClickLinkClickCount
     */
    public int getOnClickLinkClickCount()
    {
        return onClickLinkClickCount;
    }

    /**
     * Sets onClickLinkClickCount.
     * 
     * @param onClickLinkClickCount
     *            onClickLinkClickCount
     */
    public void setOnClickLinkClickCount(int onClickLinkClickCount)
    {
        this.onClickLinkClickCount = onClickLinkClickCount;
    }

    @Override
    public boolean isVersioned()
    {
        return false;
    }
}