<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%~set page_mode = $in.editor_type%><%if not page_mode or page_mode ne message%><%set page_mode = 'post'%><%endif%>
<html>
<head>
  <title>Insert Image</title>
  <link type="text/css" rel="stylesheet" media="screen" href="<%static_url%>/editor/editor_dialog.css">
  <script type="text/javascript" src="<%static_url%>/js/utils.js"></script>
  <script type="text/javascript" src="<%static_url%>/editor/editor_dialog.js"></script>
  <script type="text/javascript">
//<![CDATA[
var src = {}, activeSource, sourceTypes = ['url', 'file', 'inline'];
var inlineImages = [];
var inlines = [];
if (window.opener.getInlineAttachments)
  inlines = opener.getInlineAttachments();
<%~if attachment_uploaded%>
inlines.push(['<%escape_js attachment_uploaded%>', 'temp', '<%attachment_uploaded_id%>']);
<%~endif%>

function checkSource(submitting) {
    if (activeSource && src[activeSource + '-input'] && src[activeSource + '-input'].value && src[activeSource + '-input'].value.match(/\S/)) {
        submit.disabled = false;
        if (submitting) {
            if (activeSource == 'file')
                return true;
            else
                submitWrapper();
        }
    }
    else
        submit.disabled = true;

    return false;
}

function changeElement() {
    activeSource = false;
    for (var i = 0; i < sourceTypes.length; i++) {
        if (src[sourceTypes[i]] && src[sourceTypes[i]].checked) {
            activeSource = sourceTypes[i];
            break;
        }
    }
    if (!activeSource) return;

    for (var i = 0; i < sourceTypes.length; i++) {
        if (src[sourceTypes[i]])
            src[sourceTypes[i] + '-row'].style.display = activeSource == sourceTypes[i] ? 'block' : 'none';
    }

    if (document.getElementById('src-file'))
    {
      if (document.getElementById('src-file').checked) {
          document.getElementById('src-file-size-slider').style.display = 'flex';
          document.getElementById('src-file-quality-slider').style.display = 'flex';
          document.getElementById('src-file-size-orig').style.display = 'block';
          document.getElementById('src-file-size-resize').style.display = 'block';
      }
      else {
          document.getElementById('src-file-size-slider').style.display = 'none';
          document.getElementById('src-file-quality-slider').style.display = 'none';
          document.getElementById('src-file-size-orig').style.display = 'none';
          document.getElementById('src-file-size-resize').style.display = 'none';
      }
    }
}

function init() {
  <%~if attachment_uploaded%>
    // The upload succeeded: make the parent page refresh the attachment list
    if (opener.refreshAttachmentList)
      opener.refreshAttachmentList();
 
  <%~endif%>

    // We need to copy the temp_id from the parent document.
    document.getElementById('temp_id').value = opener.document.getElementById('temp_id').value ? opener.document.getElementById('temp_id').value : "foo";

    // Also copy over forum_id, parent_post_id, and post_id, if they exist.
    var hidden = [opener.document.getElementById('forum_id'), opener.document.getElementById('parent_post_id'), opener.document.getElementById('post_id')];
    for (var i = 0; i < hidden.length; i++) {
        if (hidden[i]) {
            var h = document.createElement('input');
            h.type = 'hidden';
            h.name = hidden[i].name;
            h.value = hidden[i].value;
            document.getElementById('image_form').appendChild(h);
        }
    }

    var eventType = isIE ? 'propertychange' : 'change';
    for (var i = 0; i < sourceTypes.length; i++) {
        var sourceType = sourceTypes[i];
        src[sourceType] = document.getElementById('src-' + sourceType);
        src[sourceType + '-input'] = document.getElementById('src-' + sourceType + '-input');
        src[sourceType + '-label'] = document.getElementById('src-' + sourceType + '-label');
        src[sourceType + '-value'] = document.getElementById('src-' + sourceType + '-value');
        src[sourceType + '-row'] = document.getElementById('src-' + sourceType + '-row');
        if (src[sourceType]) registerEvent(src[sourceType], eventType, changeElement);
    }

    if (inlines.length > 0) {
        for (i = 0; i < inlines.length; i++) {

            var filename = inlines[i][0];
            var inlineRadio;
            // Hack around a weird IE bug where setting the name attribute
            // below results in the radio button not showing its state properly
            try {
                inlineRadio = document.createElement('<input type="radio" name="inline_image" />');
            }
            catch (e) {
                inlineRadio = document.createElement('input');
            }
            inlineRadio.type = 'radio';
            inlineRadio.name = 'inline_image';
            inlineRadio.id = 'inline_image' + i;
            inlineRadio.value = filename;
          <%~if attachment_uploaded%>
            if (filename == '<%escape_js attachment_uploaded%>') {
                inlineRadio.checked = true;
                src['inline-input'].value = filename;
            }
          <%~endif%>
            var inlineLabel = document.createElement('label');
            inlineLabel.appendChild(document.createTextNode(filename));
            inlineLabel.htmlFor = 'inline_image' + i;
            var box = document.createElement('span');
            box.appendChild(inlineRadio);
            box.appendChild(inlineLabel);
            src['inline-value'].appendChild(box);
            inlineImages[inlineImages.length] = inlineRadio;
            registerEvent(inlineRadio, 'click', function(radioBox) { return function () { src['inline-input'].value = radioBox.value; }; }(inlineRadio));
        }
    }
    else {
        src['inline'].parentNode.removeChild(src['inline']);
        src['inline-label'].parentNode.removeChild(src['inline-label']);
        src['inline-row'].parentNode.removeChild(src['inline-row']);
        delete src['inline'];
        delete src['inline-label'];
        delete src['inline-row'];
    }

    if (!opener.canAttach) {
        src['file'].parentNode.removeChild(src['file']);
        src['file-label'].parentNode.removeChild(src['file-label']);
        src['file-row'].parentNode.removeChild(src['file-row']);
        delete src['file'];
        delete src['file-label'];
        delete src['file-row'];
    }

    submit = document.getElementById('submit');

    changeElement();

    setInterval(function () { checkSource() }, 250);
    if (src['url'] && src['url'].checked) document.getElementById('src-url-input').focus();

  <%~if error_loop.length%>
    alert('Error:\n<%loop error_loop%><%escape_js loop_value%><%unless last%>\n<%endunless%><%endloop%>');
  <%~elsif attachment_uploaded%>
    if (true || confirm("submit form?")) submitWrapper();
  <%~endif%>
}

function submitWrapper () {
    if (activeSource == 'inline') {
        var att_type = 'temp', att_id = 0;
        for (var i = 0; i < inlines.length; i++) {
            if (inlines[i][0] == src['inline-input'].value) {
                att_type = inlines[i][1];
                att_id = inlines[i][2];
                break;
            }
        }
        var url = '<%set url = GForum::SEO::url(params => "do=${page_mode}_attachment")%><%escape_js url%>;' + att_type + 'att_id=' + att_id;
        if (att_type == 'temp')
            url += ';<%if page_mode eq "post"%>post_unique<%else%>temp_id<%endif%>=' + document.getElementById('temp_id').value;
        src['url-input'].value = url;
    }

    submitForm();
}

registerEvent(window, 'load', init);
//]]>
  </script>
</head>
<body id="editor_image">
  <!--form id="image_form" enctype="multipart/form-data" onsubmit="return checkSource(true)"-->
  <form id="image_form" action="<%GForum::SEO::url()%>" method="post" enctype="multipart/form-data" onsubmit="return checkSource(true)">
  <%hidden_form%>
  <input type="hidden" name="do" value="<%page_mode%>_attachment_upload" />
  <input type="hidden" id="temp_id" name="temp_id" value="" /><%-- populated from parent window by init() --%>
  <input type="hidden" name="redo" value="<%this_do%>" />
  <div id="form">
    <div class="row">
      <label class="name">Insert Image from:</label>
      <input type="radio" id="src-url" name="src-type" class="radio"<%unless attachment_uploaded or error_loop.length%> checked<%endunless%>><label id="src-url-label" for="src-url" accesskey="u"><u>U</u>RL</label>
    <%~unless attachment_uploaded%>
      <input type="radio" id="src-file" name="src-type" class="radio"<%if error_loop.length%> checked<%endif%>><label id="src-file-label" for="src-file" accesskey="f"><u>F</u>ile</label>
    <%~endunless%>
      <input type="radio" id="src-inline" name="src-type" class="radio"<%if attachment_uploaded%> checked<%endunless%>><label id="src-inline-label" for="src-inline" accesskey="i"><u>I</u>nline Attachment</label>
    </div>
    <div id="src-url-row" class="row">
      <label for="src-url-input" class="name" accesskey="s">Image <u>S</u>ource:</label>
      <input type="text" id="src-url-input" value="" class="text">
    </div>
  <%~unless attachment_uploaded%>
    <div id="src-file-row" class="row">
      <label for="src-file-input" class="name" accesskey="m">I<u>m</u>age Upload:</label>
      <input type="file" accept="image/*" id="src-file-input" name="<%if page_mode eq message%>msg<%else%>post<%endif%>_attachment_orig" class="file">
      <input type="hidden" name="<%if page_mode eq message%>message<%else%>post<%endif%>_attachment_inline" value="1">
    </div>
    <div id="src-file-size-slider" style="display: none; align-items: center; gap: 8px;">
      Size:
      <input type="range" min="10" max="<%~if in.forum_id eq "1" %>1024<%~else %>256<%~endif%>" value="<%~if in.forum_id eq "1" %>512<%~else %>128<%~endif%>" id="input-size" style="max-width: 200px;"/>
      <span id="target-size"></span>
    </div>
    <div id="src-file-quality-slider" style="display: none; align-items: center; gap: 8px;">
      Quality:
      <input type="range" min="10" max="100" value="90" id="input-quality" style="max-width: 200px;"/>
    </div>
    <div id="src-file-size-orig" style="display: none;">Original: <span id="original-dimensions"></span> - <span id="original-bytesize"></span></div>
    <div id="src-file-size-resize" style="display: none;">Resized: <span id="resized-dimensions"></span> - <span id="resized-bytesize"></span></div>
    <br />
    <div>
			<img style="width: 500px; object-fit: scale-down;" id="output-img"></img>
		</div>
  <%~endunless%>
    <div id="src-inline-row" class="row">
      <input type="hidden" id="src-inline-input" value="">
      <label class="name">I<u>n</u>line Attachment:</label>
      <div id="src-inline-value" class="value"><%-- populated by init() --%></div>
    </div>
  </div>
  <div class="buttons">
    <input type="submit" id="submit" value="OK" class="submit">
    <input type="button" value="Cancel" class="button" onclick="window.close()">
  </div>
  </form>
  <div id="output-box"></div>
</body>

<%~unless attachment_uploaded%>
<script>

  let sourceImg = null
  let sourceSize = 0
  let initialized = false
  
  let inputImg = document.getElementById('src-file-input')
  let outputImg = document.getElementById('output-img')
  let inputSize = document.getElementById('input-size')
  let targetSize = document.getElementById('target-size')
  let inputQuality = document.getElementById('input-quality')
  let originalDimensions = document.getElementById('original-dimensions')
  let resizedDimensions = document.getElementById('resized-dimensions')
  let originalBytesize = document.getElementById('original-bytesize')
  let resizedBytesize = document.getElementById('resized-bytesize')

  //action="<%GForum::SEO::url()%>" method="post"
  const form = document.forms.namedItem("image_form");
  form.addEventListener(
    "submit",
    (event) => {
      event.preventDefault();

      const output = document.getElementById("output-box");
      const formData = new FormData(form);

      formData.append("CustomField", "This is some extra data");
      const imgBlob = imageToBlob(outputImg.src, 'image/jpeg');
      var imgPath = inputImg.value;
      const imgName = imgPath.replace(/^.*?([^\\\/]*)$/, '$1');
      formData.append("post_attachment", imgBlob, imgName);
      const request = new XMLHttpRequest();
      request.open("POST", "<%GForum::SEO::url()%>", true);
      request.onload = (progress) => {
      output.innerHTML =
        request.status === 200
          ? "Uploaded!"
          : `Error ${request.status} occurred when trying to upload your file.<br />`;

        if ( request.status === 200 )
        {
          
          const winUrl = URL.createObjectURL( new Blob([request.responseText], { type: "text/html" }));
          const win = window.open(
            winUrl,
            "_self"
          );
          win.opener = opener;
        }  
      };

      request.send(formData);
    },
    false
  );

  function resizeImage(image, size, quality)
  {
    let index = 0
    let canvases = [document.createElement('canvas'), document.createElement('canvas')]
    {
      canvases[index].width = image.naturalWidth
      canvases[index].height = image.naturalHeight
      const ctx0 = canvases[index].getContext('2d')
      ctx0.drawImage(image, 0, 0)
    }
  
    let finalWidth = Math.floor(image.naturalWidth * size)
    let finalHeight = Math.floor(image.naturalHeight * size)
    let iter = Math.floor(Math.sqrt((1 / size)))
  
  
    for(let i = 0; i < iter; i++)
    {	
      let canvasSrc = canvases[index]
      let canvasDst = canvases[1 - index]
      const ctxSrc = canvasSrc.getContext('2d')
      const ctxDst = canvasDst.getContext('2d')
  
      if(i == (iter - 1))
      {
        canvasDst.width = finalWidth
        canvasDst.height = finalHeight
      }
      else
      {
        canvasDst.width = canvasSrc.width / 2
        canvasDst.height = canvasSrc.height / 2
      }
  
      ctxDst.drawImage(canvasSrc, 0, 0, canvasSrc.width, canvasSrc.height, 0, 0, canvasDst.width, canvasDst.height)
  
      index = 1 - index
    }
  
    let dataURL = canvases[index].toDataURL('image/jpeg', quality)
    return dataURL
  }
  
  function getDataURLByteSize(d)
  {
    let parts = d.split(",")
    let b64size = parts[1].length
    let b64padding = parts[1].slice(-4).split('').filter(x => x == '=').length
    return 3 * ((b64size / 4)) - b64padding
  }
  
  function onResizeSourceImg()
  {
    if(!sourceImg) return
  
    targetSize.textContent = `${inputSize.value} KB`

    let dataOriginal = resizeImage(sourceImg, 1, inputQuality.value / 100)
    let sizeOriginal = getDataURLByteSize(dataOriginal)
  
    let target = 1
    if ( !initialized )
      target = Math.min( sizeOriginal, <%~if in.forum_id eq "1" %>1024000<%~else %>256000<%~endif%> );
    else
      target = inputSize.value * 1024;

    let imgRatio = Math.min( sourceImg.naturalWidth / sourceImg.naturalHeight, sourceImg.naturalHeight / sourceImg.naturalWidth );
  
    let ratio = imgRatio * Math.sqrt( Math.min(1, target / sizeOriginal)) 
  
    let dataURL = resizeImage(sourceImg, ratio, inputQuality.value / 100)
    outputImg.src = dataURL
    let size = getDataURLByteSize(dataURL)

    resizedBytesize.textContent = `${Math.floor(size / 1024)} KB`
    if ( !initialized )
    {
      targetSize.textContent = `${Math.floor(size / 1024)} KB`
      inputSize.value = Math.floor(size / 1024)
      initialized = true
    }
  }
  
  onResizeSourceImg()
  
  outputImg.onload = () => {
    if(!sourceImg) return
    resizedDimensions.textContent = `${outputImg.naturalWidth} x ${outputImg.naturalHeight}`
  }
  
  inputSize.addEventListener("input", e => {
    onResizeSourceImg()
  })
  
  inputQuality.addEventListener("input", e => {
    onResizeSourceImg()
  })
  
  inputImg.addEventListener("change", e => {
    let files = e.target.files
    if(files.length == 0) return
    let file = files[0]
  
    let fr = new FileReader()
    fr.onload = () => {
      let image = new Image()
      image.onload = () => {
        sourceImg = image
        sourceSize = file.size
  
        originalDimensions.textContent = `${image.naturalWidth} x ${image.naturalHeight}`
        originalBytesize.textContent = `${Math.floor(file.size / 1024)} KB`
  
        //inputSize.setAttribute('max', image.naturalWidth)
        //inputSize.value = image.naturalWidth * 0.5
        onResizeSourceImg()
      }
      image.src = fr.result
    }
    fr.readAsDataURL(file)
  })
  
  function imageToBlob(image, mime)
  {
    let byteString = atob(image.split(',')[1]);
    let ab = new ArrayBuffer(byteString.length);
    let ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) ia[i] = byteString.charCodeAt(i);
    let bb = new Blob([ab], { type: mime });
    return bb
  }
  
  </script>
<%~endunless%>

</html>