package com.example.meteo;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.View;
import android.widget.RemoteViews;
import android.preference.PreferenceManager;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.concurrent.ExecutionException;

/**
 * Implementation of App Widget functionality.
 * Widget periodically (30min) fetch data from URL which is set in meteo settings
 * Widget displays temperature, humidity, location and last update timestamp
 * widget can be updated manually by refresh button
 */
public class MeteoWidget extends AppWidgetProvider implements FetchData.AsyncResponse {

    public static String WIDGET_BUTTON = "android.appwidget.action.WIDGET_BUTTON";
    public static LastMeasurement measurement;

    /** updateAppWidget
     * Fetch data and update views on widget
     * */
    public void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId)
    {
        // Construct the RemoteViews object
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.meteo_widget);
        // Create Fetch data class instance
        FetchData fetchData = new FetchData();
        // Fetch and display data
        try{
            //Get url from shared preferences and fetch data from that url
            SharedPreferences preference = PreferenceManager.getDefaultSharedPreferences(context);
            String url = preference.getString("URL", "Not set");

            if(url == "Not set")
            {
                views.setTextViewText(R.id.textViewWidgetTemperature, "--,--");
                views.setTextViewText(R.id.textViewWidgetHumidity, "--,--");
                views.setTextViewText(R.id.textViewWidgetTimestamp, context.getResources().getString(R.string.toast_set_url));
                views.setTextViewText(R.id.textViewWidgetName, "----");
            }
            else {
                measurement = fetchData.execute(url).get();
                fetchData.delegate = MeteoWidget.this;

                if (measurement != null)
                {
                    SimpleDateFormat dateTimeFormat = new SimpleDateFormat(context.getResources().getString(R.string.date_time_format), Locale.getDefault());

                    views.setTextViewText(R.id.textViewWidgetTemperature, String.valueOf(measurement.temperature));
                    views.setTextViewText(R.id.textViewWidgetHumidity, String.valueOf(measurement.humidity));
                    views.setTextViewText(R.id.textViewWidgetTimestamp, dateTimeFormat.format(measurement.timestamp));
                    views.setTextViewText(R.id.textViewWidgetName, measurement.name);
                    if (measurement.temperature < 0)
                    {
                        views.setImageViewResource(R.id.widgetImageView, R.drawable.thermometer_blue);
                    }
                    else if (measurement.temperature > 0 && measurement.temperature < 25)
                    {
                        views.setImageViewResource(R.id.widgetImageView, R.drawable.thermometer_green);
                    }
                    else
                    {
                        views.setImageViewResource(R.id.widgetImageView, R.drawable.thermometer_red);
                    }
                }
                else
                {
                    views.setTextViewText(R.id.textViewWidgetTemperature, "--,--");
                    views.setTextViewText(R.id.textViewWidgetHumidity, "--,--");
                    views.setTextViewText(R.id.textViewWidgetTimestamp, context.getResources().getString(R.string.could_not_update));
                    views.setTextViewText(R.id.textViewWidgetName, "----");
                }
            }
        }
        catch (ExecutionException e)
        {
            e.printStackTrace();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        // Set widget refresh button visibility back and hide progress bar
        views.setViewVisibility(R.id.appwidget_button, View.VISIBLE);
        views.setViewVisibility(R.id.appwidget_progressBar, View.INVISIBLE);

        // Refresh widget on refresh button click (invoke onReceive there can be detected action WIDGET_BUTTON)
        Intent intent = new Intent(context,MeteoWidget.class);
        intent.setAction(WIDGET_BUTTON);
        PendingIntent.getBroadcast(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.appwidget_button, PendingIntent.getBroadcast(context, 0, intent, 0));

        // Open meteo on temperature widget click
        views.setOnClickPendingIntent(R.id.textViewWidgetTemperature,PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0));

        // Instruct the widget manager to update the widget (This refresh widget views)
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    /** onUpdate
     * Method is invoked periodically for all widgets
     * It is also invoked after refresh button click
     * */
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
    {
        // There may be multiple widgets active, so update all of them
        for (int appWidgetId : appWidgetIds)
        {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    /** onReceive
     * Method is invoked when event from widget is received
     * */
    @Override
    public void onReceive(Context context, Intent intent)
    {
        super.onReceive(context, intent);

        // process widget refresh button click
        if (WIDGET_BUTTON.equals(intent.getAction()))
        {
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.meteo_widget);
            // Unset widget refresh button visibility and show progress bar
            views.setViewVisibility(R.id.appwidget_button, View.INVISIBLE);
            views.setViewVisibility(R.id.appwidget_progressBar, View.VISIBLE);
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
            int[] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, MeteoWidget.class));

            for (int appWidgetId : ids)
            {
                appWidgetManager.updateAppWidget(appWidgetId, views);
            }
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
            context.sendBroadcast(intent);
        }
    }

    @Override
    public void processFinish(LastMeasurement lastMeasurement)
    {
        // Data are fetched in updateAppWidget() directly
    }
}