package com.lemenzo.clock.alarm;
import android.app.*;import android.content.*;import com.lemenzo.clock.ClockActivity;import com.lemenzo.clock.model.Alarm;import java.util.*;
public final class AlarmScheduler {
 private final Context c;private final AlarmManager m;public AlarmScheduler(Context c){this.c=c.getApplicationContext();m=c.getSystemService(AlarmManager.class);}
 public void schedule(Alarm a){if(m==null||a==null||!a.enabled)return;long when=nextScheduled(a,System.currentTimeMillis());scheduleAt(a,when);}
 public void skipNext(Alarm a){if(a==null||!a.enabled||a.repeatDays.isEmpty())return;a.skippedOccurrenceAt=next(a,System.currentTimeMillis());new AlarmRepository(c).save(a);schedule(a);}
 public static long nextScheduled(Alarm a,long now){long first=next(a,now);if(a.skippedOccurrenceAt>0&&sameMinute(first,a.skippedOccurrenceAt))return next(a,first+1000L);return first;}
 public static void clearConsumedSkip(Alarm a,long now){if(a!=null&&a.skippedOccurrenceAt>0&&a.skippedOccurrenceAt<now){a.skippedOccurrenceAt=0L;}}
 private static boolean sameMinute(long a,long b){return Math.abs(a-b)<60000L;}
 private void scheduleAt(Alarm a,long when){Intent fire=new Intent(c,AlarmReceiver.class).setAction(AlarmIntentActions.FIRE).putExtra(AlarmIntentActions.EXTRA_ID,a.id);PendingIntent op=PendingIntent.getBroadcast(c,code(a.id),fire,PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE);PendingIntent show=PendingIntent.getActivity(c,code(a.id)^0x4c4d,new Intent(c,ClockActivity.class).setAction(android.provider.AlarmClock.ACTION_SHOW_ALARMS),PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE);m.setAlarmClock(new AlarmManager.AlarmClockInfo(when,show),op);}
 public void cancel(long id){if(m==null)return;PendingIntent p=PendingIntent.getBroadcast(c,code(id),new Intent(c,AlarmReceiver.class).setAction(AlarmIntentActions.FIRE),PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_IMMUTABLE);if(p!=null)m.cancel(p);}
 public static long next(Alarm a,long nowMs){Calendar base=Calendar.getInstance();base.setTimeInMillis(nowMs);for(int add=0;add<8;add++){Calendar x=(Calendar)base.clone();x.add(Calendar.DAY_OF_YEAR,add);x.set(Calendar.HOUR_OF_DAY,a.hour);x.set(Calendar.MINUTE,a.minute);x.set(Calendar.SECOND,0);x.set(Calendar.MILLISECOND,0);if(x.getTimeInMillis()<=nowMs)continue;if(a.repeatDays.isEmpty()||a.repeatDays.contains(x.get(Calendar.DAY_OF_WEEK)))return x.getTimeInMillis();}Calendar x=(Calendar)base.clone();x.add(Calendar.DAY_OF_YEAR,1);x.set(Calendar.HOUR_OF_DAY,a.hour);x.set(Calendar.MINUTE,a.minute);x.set(Calendar.SECOND,0);x.set(Calendar.MILLISECOND,0);return x.getTimeInMillis();}
 public static Alarm nextEnabled(List<Alarm> alarms,long now){Alarm best=null;long bestAt=Long.MAX_VALUE;for(Alarm a:alarms){if(!a.enabled)continue;long at=nextScheduled(a,now);if(at<bestAt){bestAt=at;best=a;}}return best;}
 private static int code(long id){return (int)(id^(id>>>32));}
}