<|start_filename|>mural/src/main/java/com/irozon/mural/Utils.kt<|end_filename|>
package com.irozon.mural

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint

/**
 * Created by hammad.akram on 3/1/18.
 */

object Utils {

    fun getScreenHeightWithStatusBar(context: Context): Int {
        val dm = context.resources.displayMetrics
        return dm.heightPixels
    }

    fun getScreenHeight(context: Context?): Int? {
        val dm = context?.resources?.displayMetrics
        return dm?.heightPixels?.minus(getStatusBarHeight(context))
    }

    fun getScreenWidth(context: Context?): Int? {
        val dm = context?.resources?.displayMetrics
        return dm?.widthPixels
    }

    fun getStatusBarHeight(context: Context?): Int {
        var result = 0
        val resourceId = context?.resources?.getIdentifier("status_bar_height", "dimen", "android")
        if (resourceId != null) {
            if (resourceId > 0) {
                result = context.resources.getDimensionPixelSize(resourceId)
            }
        }
        return result
    }

    fun createImage(width: Int, height: Int, color: Int): Bitmap {
        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint()
        paint.color = color
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
        return bitmap
    }
}


<|start_filename|>mural/src/main/java/com/irozon/mural/manager/PlaceHolder.kt<|end_filename|>
package com.irozon.mural.manager

import android.graphics.Bitmap

/**
 * Created by <NAME> on 3/1/2018.
 */
object PlaceHolder {
    var placeHolder: Int = 0
    var placeHolderBitmap: Bitmap? = null
    var placeHolderColor: Int = -1
}


<|start_filename|>mural/src/main/java/com/irozon/mural/Mural.kt<|end_filename|>
package com.irozon.mural

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.support.annotation.AnyRes
import android.support.annotation.DrawableRes
import android.widget.ImageView

import com.irozon.mural.async.LoadBitmapFromDrawableTask
import com.irozon.mural.async.LoadBitmapFromURLTask
import com.irozon.mural.cache.ImageCache
import com.irozon.mural.manager.PlaceHolder
import java.lang.ref.WeakReference


/**
 * Created by <NAME> on 3/1/18.
 */

class Mural {
    private var mUrl: String? = null
    private var enableCache = true
    private var mRes: Int = 0
    private var mPlaceHolderBitmap: Bitmap? = null
    private var mWidth = DEFAULT_WIDTH
    private var mHeight = DEFAULT_HEIGHT
    private var cacheAllowed = 1f

    companion object {
        private var contextWeakReference: WeakReference<Context>? = null
        private lateinit var muralWeakReference: WeakReference<Mural>
        var DEFAULT_WIDTH = 500
        var DEFAULT_HEIGHT = 500

        fun with(context: Context): Mural {

            contextWeakReference = WeakReference(context)

            val mural = Mural()
            muralWeakReference = WeakReference(mural)

            DEFAULT_HEIGHT = Utils.getScreenHeight(getContext())!!
            DEFAULT_WIDTH = Utils.getScreenWidth(getContext())!!

            return getMural()
        }
        private fun getContext(): Context? {
            return contextWeakReference?.get()
        }

        private fun getMural(): Mural {
            return muralWeakReference.get()!!
        }
    }

    /**
     * Image source by url
     * @param url
     */
    fun source(url: String): Mural {
        mUrl = url
        mRes = -100
        return getMural()
    }

    /**
     * Image source by drawable resource
     * @param res
     */
    fun source(@DrawableRes res: Int): Mural {
        mRes = res
        mUrl = null
        return getMural()
    }

    /**
     * Resize image
     * @param width
     * @param height
     */
    fun resize(width: Int, height: Int): Mural {
        if (width != 0)
            mWidth = width
        if (height != 0)
            mHeight = height
        return getMural()
    }

    /**
     * Placeholder image
     * @param placeholder - Drawable
     */
    fun placeholder(@AnyRes placeholder: Int): Mural {
        if (placeholder != PlaceHolder.placeHolder) {
            try {
                // Try for drawable resource
                mPlaceHolderBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getContext()?.resources, placeholder), 300, 300, true)
                PlaceHolder.placeHolder = placeholder
                PlaceHolder.placeHolderBitmap = mPlaceHolderBitmap
                PlaceHolder.placeHolderColor = -1
            } catch (ignored: Exception) {
                PlaceHolder.placeHolder = placeholder
                PlaceHolder.placeHolderBitmap = null
                PlaceHolder.placeHolderColor = placeholder
            }

        } else {
            mPlaceHolderBitmap = PlaceHolder.placeHolderBitmap
        }
        return getMural()
    }

    /**
     * Enable cache and set cache size - 0 to 1f
     * @param percent
     */
    fun enableCache(percent: Float): Mural {
        enableCache = true
        cacheAllowed = percent
        return getMural()
    }

    /**
     * Disable cache
     */
    fun disableCache(): Mural {
        enableCache = false
        cacheAllowed = 0f
        return getMural()
    }

    /**
     * Load image to an ImageView
     * @param imageView
     */
    fun loadImage(imageView: ImageView) {
        var imageCache: ImageCache? = null
        var bitmap: Bitmap? = null
        if (enableCache) {
            /*Get imageCache instance*/
            imageCache = ImageCache[getContext(), cacheAllowed]
            var imageKey: String? = null
            if (mUrl != null) {
                imageKey = mUrl
            }
            if (mRes != -100) {
                imageKey = mRes.toString()
            }
            bitmap = imageCache.get(imageKey)
        }
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap)
        } else {
            if (mUrl != null) { /*Load using url*/
                val task = LoadBitmapFromURLTask(imageView, imageCache, enableCache, mWidth, mHeight, mUrl!!)

                // Set Placeholder
                if (PlaceHolder.placeHolderBitmap != null) { // Placeholder is bitmap
                    imageView.setImageBitmap(PlaceHolder.placeHolderBitmap)
                } else if (PlaceHolder.placeHolderColor != -1) { // Placeholder is color
                    imageView.setImageResource(PlaceHolder.placeHolderColor)
                }

                task.execute()
            }
            if (mRes != -100) { /*Load using Drawable resource*/
                val task = LoadBitmapFromDrawableTask(getContext(), imageView, imageCache, enableCache, mWidth, mHeight, mRes)

                // Set Placeholder
                if (PlaceHolder.placeHolderBitmap != null) { // Placeholder is bitmap
                    imageView.setImageBitmap(PlaceHolder.placeHolderBitmap)
                } else if (PlaceHolder.placeHolderColor != -1) { // Placeholder is color
                    imageView.setImageResource(PlaceHolder.placeHolderColor)
                }

                task.execute()
            }
        }
    }
}

<|start_filename|>mural/src/main/java/com/irozon/mural/async/LoadBitmapFromDrawableTask.kt<|end_filename|>
package com.irozon.mural.async

import android.content.Context
import android.widget.ImageView
import com.irozon.mural.cache.ImageCache
import com.irozon.mural.manager.ImageFetcher
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread

/**
 * Created by <NAME> on 3/1/2018.
 */
class LoadBitmapFromDrawableTask(private val mContext: Context?, private val imageView: ImageView, private val mCache: ImageCache?, private val mCacheImage: Boolean, private val mWidth: Int, private val mHeight: Int, var res: Int) {
    fun execute() {
        doAsync {
            val bitmap = mContext?.let { ImageFetcher.decodeSampledBitmapFromDrawable(it, res, mWidth, mHeight) }
            uiThread {
                if (mCacheImage) {
                    mCache?.put(res.toString(), bitmap)
                }
                imageView.setImageBitmap(bitmap)
            }
        }
    }
}



<|start_filename|>mural/src/main/java/com/irozon/mural/async/LoadBitmapFromURLTask.kt<|end_filename|>
package com.irozon.mural.async

import android.widget.ImageView

import com.irozon.mural.cache.ImageCache
import com.irozon.mural.manager.ImageFetcher
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread

import java.net.MalformedURLException
import java.net.URL

/**
 * Created by <NAME> on 3/1/2018.
 */
class LoadBitmapFromURLTask(private val imageView: ImageView, private val mCache: ImageCache?, private val mCacheImage: Boolean, private val mWidth: Int, private val mHeight: Int, private val strUrl: String) {

    fun execute() {
        doAsync {
            var url: URL? = null
            try {
                url = URL(strUrl)
            } catch (e: MalformedURLException) {
                e.printStackTrace()
            }
            if (url != null) {
                val bitmap = ImageFetcher.decodeSampledBitmapFromUrl(url, mWidth, mHeight)
                uiThread {
                    if (mCacheImage) {
                        mCache?.put(strUrl, bitmap)
                    }
                    imageView.setImageBitmap(bitmap)

                }
            }
        }
    }
}



<|start_filename|>mural/src/main/java/com/irozon/mural/cache/ConfigCache.kt<|end_filename|>
package com.irozon.mural.cache

import android.util.Log

/**
 * Created by <NAME> on 3/1/2018.
 */
object ConfigCache {
    fun setMemCacheSizePercent(percent: Float): Float {
        if (percent > 1f) {
            Log.w("Cache size warning", "Cache should be less than 1(100%). Setting 25%")
            return 25f
        }
        return percent
    }
}


<|start_filename|>mural/src/main/java/com/irozon/mural/extension/ImageViewExt.kt<|end_filename|>
package com.irozon.mural.extension

import android.graphics.drawable.Drawable
import android.widget.ImageView
import com.irozon.mural.Mural

/**
 * Created by hammad.akram on 3/9/18.
 */

var ImageView.source: Any
    get() = ""
    set(value) {
        if (value is String) {
            Mural.with(this.context).source(value).loadImage(this)
        }
        else if (value is Int)
            Mural.with(this.context).source(value).loadImage(this)
    }

var ImageView.placeholder: Drawable?
    get() = null
    set(source) {
        this.setImageDrawable(source)
    }


<|start_filename|>mural/src/main/java/com/irozon/mural/cache/ImageCache.kt<|end_filename|>
package com.irozon.mural.cache

import android.app.ActivityManager
import android.content.Context
import android.graphics.Bitmap
import android.support.v4.util.LruCache

/**
 * Created by <NAME> on 3/1/2018.
 */
class ImageCache(maxSize: Int) : LruCache<String, Bitmap>(maxSize) {

    override fun sizeOf(key: String?, value: Bitmap?): Int {
        return value!!.rowBytes * value.height
    }

    companion object {

        private var instance: ImageCache? = null

        operator fun get(context: Context?, cacheAllowed: Float): ImageCache {
            if (instance == null) {
                val am = context?.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
                val memClassBytes = (am.memoryClass * 1024 * 1024).toFloat()
                val cacheSize = memClassBytes * cacheAllowed
                instance = ImageCache(Math.round(cacheSize))
            }
            return instance as ImageCache
        }
    }
}


<|start_filename|>app/src/main/java/com/irozon/muralsample/MainActivity.kt<|end_filename|>
package com.irozon.muralsample

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.irozon.mural.extension.placeholder
import com.irozon.mural.extension.source
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ivImage.placeholder = resources.getDrawable(R.drawable.placeholder)
        ivImage.source = "http://blog.europeana.eu/wp-content/uploads/2017/01/2063604_DEN_280_010.jpeg"
    }
}