<%--
    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.
--%>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
<%@ page import="java.util.Properties"%>
<%@ page import="org.apache.commons.text.*" %>
<%@ page import="org.apache.wiki.api.core.*" %>
<%@ page import="org.apache.wiki.auth.*" %>
<%@ page import="org.apache.wiki.auth.permissions.*" %>
<%@ page import="org.apache.wiki.filters.*" %>
<%@ page import="org.apache.wiki.pages.PageManager" %>
<%@ page import="org.apache.wiki.parser.MarkupParser" %>
<%@ page import="org.apache.wiki.render.*" %>
<%@ page import="org.apache.wiki.ui.*" %>
<%@ page import="org.apache.wiki.util.TextUtil" %>
<%@ page import="org.apache.wiki.variables.VariableManager" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<fmt:setLocale value="${prefs.Language}" />
<fmt:setBundle basename="templates.default"/>
<%--
    This provides the WYSIWYG TinyMCE for JSPWiki.
--%>
<%
    Context context = Context.findContext( pageContext );
    Engine engine = context.getEngine();

    /* local download of TinyMCE */
    TemplateManager.addResourceRequest( context, TemplateManager.RESOURCE_SCRIPT,
           context.getURL( ContextEnum.PAGE_NONE.getRequestContext(), "scripts/tinymce/js/tinymce/tinymce.min.js" ) );

    /*  Use TinyMCE from a CDN
    TemplateManager.addResourceRequest( context, TemplateManager.RESOURCE_SCRIPT, "//tinymce.cachefly.net/4.2/tinymce.min.js" );
    */

    context.setVariable( Context.VAR_WYSIWYG_EDITOR_MODE, Boolean.TRUE );
    context.setVariable( VariableManager.VAR_RUNFILTERS,  "false" );

    Page wikiPage = context.getPage();
    String originalCCLOption = (String)wikiPage.getAttribute( MarkupParser.PROP_CAMELCASELINKS );
    wikiPage.setAttribute( MarkupParser.PROP_CAMELCASELINKS, "false" );

    String usertext = EditorManager.getEditedText(pageContext);

%>
<wiki:CheckRequestContext context="edit">
<wiki:NoSuchPage> <%-- this is a new page, check if we're cloning --%>
<%
  String clone = request.getParameter( "clone" );
  if( clone != null )
  {
    Page p = engine.getManager( PageManager.class ).getPage( clone );
    if( p != null )
    {
        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
        PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );

        try
        {
          if( mgr.checkPermission( context.getWikiSession(), pp ) )
          {
            usertext = engine.getManager( PageManager.class ).getPureText( p );
          }
        }
        catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
    }
  }
%>
</wiki:NoSuchPage>
<%
  if( usertext == null )
  {
    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
  }
%>
</wiki:CheckRequestContext>
<%
   if( usertext == null ) usertext = "";

   String pageAsHtml;
   try {
       //pageAsHtml = StringEscapeUtils.escapeJavaScript( engine.getManager( RenderingManager.class ).getHTML( context, usertext ) );
       pageAsHtml = engine.getManager( RenderingManager.class ).getHTML( context, usertext );
   } catch( Exception e ) {
       pageAsHtml = "Error in converting wiki-markup to well-formed HTML \n" + e.toString();
       //pageAsHtml = e.toString() + "\n" + usertext; //error
   }

   // Disable the WYSIWYG_EDITOR_MODE and reset the other properties immediately
   // after the XHTML for TinyMCE has been rendered.
   context.setVariable( Context.VAR_WYSIWYG_EDITOR_MODE, Boolean.FALSE );
   context.setVariable( VariableManager.VAR_RUNFILTERS,  null );
   wikiPage.setAttribute( MarkupParser.PROP_CAMELCASELINKS, originalCCLOption );

   /*not used
   String templateDir = (String)engine.getWikiProperties().get( Engine.PROP_TEMPLATEDIR );

   String protocol = "http://";
   if( request.isSecure() )
   {
       protocol = "https://";
   }
   */
%>
<form method="post" accept-charset="<wiki:ContentEncoding/>"
      action="<wiki:CheckRequestContext
     context='edit'><wiki:EditLink format='url'/></wiki:CheckRequestContext><wiki:CheckRequestContext
     context='comment'><wiki:CommentLink format='url'/></wiki:CheckRequestContext>"
       class="editform wysiwyg"
          id="editform"
     enctype="application/x-www-form-urlencoded" >

    <%-- Edit.jsp relies on these being found.  So be careful, if you make changes. --%>
  <input type="hidden" name="page" value="<wiki:Variable var='pagename' />" />
  <input type="hidden" name="action" value="save" />
  <%=SpamFilter.insertInputFields( pageContext )%>
  <input type="hidden" name="<%=SpamFilter.getHashFieldName(request)%>" value="${lastchange}" />
  <%-- This following field is only for the SpamFilter to catch bots which are just randomly filling all fields and submitting.
       Normal user should never see this field, nor type anything in it. --%>
  <div style="display:none;">Authentication code: <input type="text" name="<%=SpamFilter.getBotFieldName()%>" id="<%=SpamFilter.getBotFieldName()%>" value="" /></div>

    <p>
      <input name='ok' type='submit' value='<fmt:message key="editor.plain.save.submit"/>' />
      <input name='preview' type='submit' value='<fmt:message key="editor.plain.preview.submit"/>' />
      <input name='cancel' type='submit' value='<fmt:message key="editor.plain.cancel.submit"/>' />

      <wiki:CheckRequestContext context="edit">
      <label for="changenote"><fmt:message key='editor.plain.changenote'/></label>
      <input type="text" id="changenote" name="changenote" size="80" maxlength="80" value="${changenote}"/>
      </wiki:CheckRequestContext>
    </p>
    <wiki:CheckRequestContext context="comment">
      <fieldset>
	    <legend><fmt:message key="editor.commentsignature"/></legend>
        <p>
          <label for="authorname" accesskey="n"><fmt:message key="editor.plain.name"/></label>

          <%--<input type="text" name="author" id="authorname" value="${author}" />--%>
          <input type="text" name="author" id="authorname" value="<c:out value='${sessionScope.author}' />" />

          <input type="checkbox" name="remember" id="rememberme" <%=TextUtil.isPositive((String)session.getAttribute("remember")) ? "checked='checked'" : ""%> />
          <label for="rememberme"><fmt:message key="editor.plain.remember"/></label>
        </p>
	    <%--FIXME: seems not to read the email of the user, but some odd previously cached value --%>
        <p>
          <label for="link" accesskey="m"><fmt:message key="editor.plain.email"/></label>
          <%--<input type="text" name="link" id="link" size="24" value="${link}" />--%>
          <input type="text" name="link" id="link" size="24" value="<c:out value='${sessionScope.link}' />" />
        </p>
      </fieldset>
    </wiki:CheckRequestContext>

    <textarea name="htmlPageText"><%=pageAsHtml%></textarea>
</form>
<script type="text/javascript">
//<![CDATA[

/* some helper function */
    /*
    Event: debounce
        Returns a function, that, as long as it continues to be invoked, will not
        be triggered. The function will be called after it stops being called for
        N milliseconds. If `immediate` is passed, trigger the function on the
        leading edge, instead of the trailing.
        I.e. collapse a number of events into a single event.

    Credits:
        http://davidwalsh.name/function-debounce

    Example:
        el.addEvent('resize', resizePage.debounce(250, true).bind(this) );
    */
    function debounce(func, wait, immediate){

        var timer;

        return function(){

            var args = arguments,
                context = this,
                callNow = immediate && !timer;

            function later(){
                timer = null;
                if( !immediate ){ func.apply(context, args); }
            }

            clearTimeout(timer);
            timer = setTimeout(later, wait || 250);

            if( callNow ){ func.apply(context, args); }

        };

    }


Wiki.addPageRender({

render: function( page, name ){

  $ES("[name=htmlPageText]", page).each( function(element){

    var editor;

    tinymce.init({
      selector: "textarea[name=htmlPageText]",
      //content_css : "template/haddock/haddock.css",
      //extended_valid_elements: "...]",
      //invalid_elements: blockquote ...",
      language: Wiki.prefs.get( "Language" ), //"${prefs.Language}",
      height: Wiki.prefs.get( "EditorCookie" ),
      content_css: $("main-stylesheet").href,
      //plugins from the standard 4.2.2. package
      plugins: 'anchor charmap code fullscreen image insertdatetime link lists media paste preview searchreplace table wordcount',

      setup: function( ed ){

        editor = ed;

        editor.on("init", function(){
            //resizePreview...
        });
        editor.on("ResizeEditor", ( debounce( function(){
           Wiki.prefs.set("EditorCookie", $(editor.getContentAreaContainer()).getStyle("height") );
        }) ) );
        //editor.on("change", html2markup );

      }
    });
  });
}

});

//]]>
</script>
