package fr.ydelouis.selfoss.rest;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.OrmLiteDao;
import org.androidannotations.annotations.rest.RestService;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import fr.ydelouis.selfoss.entity.Article;
import fr.ydelouis.selfoss.entity.ArticleType;
import fr.ydelouis.selfoss.entity.Tag;
import fr.ydelouis.selfoss.model.ArticleSyncActionDao;
import fr.ydelouis.selfoss.model.DatabaseHelper;
import fr.ydelouis.selfoss.sync.ArticleSyncAction;
import fr.ydelouis.selfoss.util.ArticleContentParser;

@EBean
public class SelfossRestWrapper {

    @RestService
    protected SelfossRest rest;
    @OrmLiteDao(helper = DatabaseHelper.class)
    protected ArticleSyncActionDao articleSyncActionDao;

    public List<Article> listArticles(int offset, int count) {
        return preProcess(rest.listArticles(offset, count));
    }

    public List<Article> listArticles(Tag tag, int offset, int count) {
        return preProcess(rest.listArticles(tag, offset, count));
    }

    public List<Article> listArticles(int sourceId, int offset, int count) {
        return preProcess(rest.listArticles(sourceId, offset, count));
    }

    public List<Article> listArticles(ArticleType type, Tag tag, int offset, int count) {
        return preProcess(rest.listArticles(type, tag, offset, count));
    }

    public List<Article> listArticles(ArticleType type, int sourceId, int offset, int count) {
        return preProcess(rest.listArticles(type, sourceId, offset, count));
    }

    public List<Article> listArticles(ArticleType type, int offset, int count) {
        return preProcess(rest.listArticles(type, offset, count));
    }

    public List<Article> listUnreadArticles(int offset, int count) {
        return preProcess(rest.listUnreadArticles(offset, count));
    }

    public List<Article> listStarredArticles(int offset, int count) {
        return preProcess(rest.listStarredArticles(offset, count));
    }

    private List<Article> preProcess(List<Article> articles) {
        if (articles != null) {
            for (Article article : articles) {
                preProcess(article);
            }
        }
        return articles;
    }

    private void preProcess(Article article) {
        applySyncAction(article);
        extractImage(article);
    }

    private void applySyncAction(Article article) {
        ArticleSyncAction syncAction = articleSyncActionDao.queryForArticle(article);
        if (syncAction != null) {
            syncAction.getAction().execute(article);
        }
    }

    private void extractImage(Article article) {
        ArticleContentParser parser = new ArticleContentParser(article);
        List<String> imageUrls = parser.extractImageUrls();
        for (String imageUrl : imageUrls) {
            Bitmap bitmap = loadBitmap(imageUrl);
            if (bitmap != null && !bitmapIsEmpty(bitmap)) {
                article.setImageUrl(imageUrl);
                return;
            }
        }
    }

    private Bitmap loadBitmap(String imageUrl) {
        try {
            URL url = new URL(imageUrl);
            URLConnection connection = url.openConnection();
            return BitmapFactory.decodeStream(connection.getInputStream());
        } catch (IOException e) {
            return null;
        }
    }

    private boolean bitmapIsEmpty(Bitmap bitmap) {
        if (bitmap.getWidth() < 50 || bitmap.getHeight() < 50) {
            return true;
        }
        for (int x = 0; x < bitmap.getWidth(); x++) {
            for (int y = 0; y < bitmap.getHeight(); y++) {
                if (bitmap.getPixel(x, y) != Color.WHITE) {
                    return false;
                }
            }
        }
        return true;
    }

}

@@ -24,24 +24,56 @@
 foss.rest;%0A%0A
+import android.content.Context;%0A
 import andro
@@ -116,29 +116,132 @@
 raphics.
-BitmapFactory
+Color;%0Aimport android.widget.ImageView;%0A%0Aimport com.androidquery.AQuery;%0Aimport com.androidquery.callback.AjaxStatus
 ;%0Aimport
@@ -245,32 +245,109 @@
 ort 
+com.
 android
-.graphics.Color;%0A
+query.callback.BitmapAjaxCallback;%0A%0Aimport org.androidannotations.annotations.AfterInject;
 %0Aimp
@@ -442,24 +442,79 @@
 OrmLiteDao;%0A
+import org.androidannotations.annotations.RootContext;%0A
 import org.a
@@ -578,97 +578,61 @@
 ava.
-io.IOException;%0Aimport java.net.URL;%0Aimport java.net.URLConnection;%0Aimport java.util.List
+util.List;%0Aimport java.util.concurrent.CountDownLatch
 ;%0A%0Ai
@@ -1163,16 +1163,196 @@
 tionDao;
+%0A    @RootContext%0A    protected Context context;%0A    private AQuery aQuery;%0A%0A    @AfterInject%0A    protected void init() %7B%0A        aQuery = new AQuery(new ImageView(context));%0A    %7D
 %0A%0A    pu
@@ -3417,26 +3417,43 @@
 itmap = 
-load
+new 
 Bitmap
+Downloader().load
 (imageUr
@@ -3622,325 +3622,8 @@
  %7D%0A%0A
-    private Bitmap loadBitmap(String imageUrl) %7B%0A        try %7B%0A            URL url = new URL(imageUrl);%0A            URLConnection connection = url.openConnection();%0A            return BitmapFactory.decodeStream(connection.getInputStream());%0A        %7D catch (IOException e) %7B%0A            return null;%0A        %7D%0A    %7D%0A%0A
     
@@ -4046,10 +4046,692 @@
 %0A    %7D%0A%0A
+    private class BitmapDownloader %7B%0A        private Bitmap bitmap;%0A%0A        public Bitmap load(String imageUrl) %7B%0A            final CountDownLatch latch = new CountDownLatch(1);%0A            aQuery.image(imageUrl, true, true, 200, 0, new BitmapAjaxCallback() %7B%0A                @Override%0A                protected void callback(String url, ImageView iv, Bitmap bm, AjaxStatus status) %7B%0A                    bitmap = bm;%0A                    latch.countDown();%0A                %7D%0A            %7D);%0A            try %7B%0A                latch.await();%0A            %7D catch (InterruptedException e) %7B%0A                e.printStackTrace();%0A            %7D%0A            return bitmap;%0A        %7D%0A    %7D%0A%0A
 %7D%0A

Use AQuery to pre-fetch images to reduce bandwidth