/* android_print.cpp */

/* printing support for Tux Paint */

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  (See COPYING.txt)

*/

// Based on JNI and PrintHelper class
// https://developer.android.com/reference/android/support/v4/print/PrintHelper.html
// https://developer.android.com/training/printing/photos.html

#include "../../SDL2/src/core/android/SDL_android.h"
#include "android_print.h"
#include "jni.h"

/* FIXME: Is this check still needed after the change from android/support/v4 to AndroidX 
   and being Android 5 the minimum version we support? */
// Since Print work is based on Java PrintHelper class, which may not be supported on some old versions
int IsPrinterAvailable(void)
{
  JNIEnv *mEnv = Android_JNI_GetEnv();
  jclass mPrintHelperClass = (*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");

  if (mPrintHelperClass == NULL)
    return 0;

  jmethodID mSupportMethod = (*mEnv)->GetStaticMethodID(mEnv, mPrintHelperClass, "systemSupportsPrint",
                                                        "()Z");
  jboolean support = (*mEnv)->CallStaticBooleanMethod(mEnv, mPrintHelperClass, mSupportMethod);

  return support ? 1 : 0;
}

// This function is based on 
// (1) convert surface to Java BitMap object
// (2) call Java PrintHelper to do print job.
const char *SurfacePrint(SDL_Surface *surface)
{
  JNIEnv *mEnv = Android_JNI_GetEnv();
  jclass mBitmapClass = (*mEnv)->FindClass(mEnv, "android/graphics/Bitmap");
  jmethodID mCreateMethod = (*mEnv)->GetStaticMethodID(mEnv, mBitmapClass, "createBitmap",
                                                       "([IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
  jintArray mSurfaceArray = (*mEnv)->NewIntArray(mEnv, surface->w * surface->h);

  (*mEnv)->SetIntArrayRegion(mEnv, mSurfaceArray, 0, surface->w * surface->h, surface->pixels);
  jclass mConfigClass = (*mEnv)->FindClass(mEnv, "android/graphics/Bitmap$Config");
  jfieldID mConfigField = (*mEnv)->GetStaticFieldID(mEnv, mConfigClass, "ARGB_8888",
                                                    "Landroid/graphics/Bitmap$Config;");
  jobject mConfig = (*mEnv)->GetStaticObjectField(mEnv, mConfigClass, mConfigField);
  jobject mBitMap = (*mEnv)->CallStaticObjectMethod(mEnv, mBitmapClass, mCreateMethod,
                                                    mSurfaceArray, surface->w, surface->h,
                                                    mConfig);

  jobject mContext = (jobject) SDL_AndroidGetActivity();
  jclass mPrintClass = (*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");

  // sometimes android v4 support library may be not ready
  if (mPrintClass == NULL)
    return "There is no androidX support library.";
  jmethodID mInitMethod = (*mEnv)->GetMethodID(mEnv, mPrintClass, "<init>",
                                               "(Landroid/content/Context;)V");
  jobject mPrint = (*mEnv)->NewObject(mEnv, mPrintClass, mInitMethod, mContext);
  jmethodID mPrintMethod = (*mEnv)->GetMethodID(mEnv, mPrintClass, "printBitmap",
                                                "(Ljava/lang/String;Landroid/graphics/Bitmap;)V");

  /* Thanks to n.collins for the explaination on the int signature
     on https://stackoverflow.com/questions/13468041/android-how-to-call-java-method-from-jni-with-int-and-int-parameters  --Pere */
  jmethodID msetScaleMode = (*mEnv)->GetMethodID(mEnv, mPrintClass, "setScaleMode", "(I)V");
  jfieldID mScaleModeField = (*mEnv)->GetStaticFieldID(mEnv, mPrintClass, "SCALE_MODE_FIT", "I");
  jint mScaleModeInt = (*mEnv)->GetStaticIntField(mEnv, mPrintClass, mScaleModeField);

  (*mEnv)->CallVoidMethod(mEnv, mPrint, msetScaleMode, mScaleModeInt);

  jstring mString = (*mEnv)->NewStringUTF(mEnv, "TuxPaint");

  (*mEnv)->CallVoidMethod(mEnv, mPrint, mPrintMethod, mString, mBitMap);

  // clean up
  (*mEnv)->DeleteLocalRef(mEnv, mSurfaceArray);
  (*mEnv)->DeleteLocalRef(mEnv, mConfig);
  (*mEnv)->DeleteLocalRef(mEnv, mPrint);
  (*mEnv)->DeleteLocalRef(mEnv, mString);
  return NULL;
}
