(* Programmautor: Pit Noack *)
(* Eingabestrings fr Ort und Zeitraum interpretieren *)

getPositionFromString[input_] := Interpreter["Location"][input]
getDateFromString[input_] := Interpreter["Date"][input]

(* Erdbebendaten abfragen und als zweidimensionale Liste {{Datum, \
Magnitude, Ort}, ... } formatieren *)

getEarthquakeData[center_, sideLength_, start_, end_, magnitude_] :=
 
 Module[{quakesRaw, searchArea},
  searchArea = GeoDisk[center, Quantity[sideLength/2, "Kilometers"]];
  quakesRaw = EarthquakeData[searchArea, magnitude, {start, end}];
  If[MatchQ[quakesRaw, _Association], 
   Map[{#["Period"], #["Magnitude"], #["Position"]} &, 
    Values[quakesRaw]], {}]
  ]

(*CTextinfo rendern *)

renderTextInfos[data_, center_, start_, end_, filename_] :=
 Column[{
   Text[Style["Auswertung", Bold, FontSize -> 14]],
   "Zentrum: " center,
   "Seitenlnge: " <> ToString[sideLength] <> " km",
   "Zeitraum: " start - end,
   "Magnitude min: " <> ToString[data[[All, 2]] // Min],
   "Magnitude max: " <> ToString[data[[All, 2]] // Max],
   "Anzahl Erdbeben: " <> ToString[data // Length]
   }, Spacings -> {0, 1}]

(* Erdbenenkarte rendern*)

renderEarthquakeMap[data_] :=
 GeoGraphics[
  {Apply[{RGBColor[1, 0, 1, 0.4], PointSize[0.0003 (#2 ^2.5)], 
      Point[#3]} &, data, {1}]},
  GeoRange -> Automatic,
  GeoScaleBar -> "Kilometers",
  GeoRangePadding -> Scaled[0.05],
  GeoBackground -> GeoStyling["ReliefMap"],
       ImageSize -> 700
  
  ]

(* Histogram Hufigkeit vs. Zeitinterval rendern*)

renderIntervalHistogram[data_, start_, end_] :=
 
 Module[{difference,  segmentation},
  difference = DateDifference[start, end][[1]]/365;
  Which[
   difference > 1 , segmentation = "Year",
   difference <= 1  && difference > 0.2, segmentation  = "Month",
   difference <= 0.2, segmentation = "Day"
   ];
  DateHistogram[Map[First, data], segmentation,
   AxesLabel -> {"Interval", "Anzahl Beben"},
   ImagePadding -> 60,
   ChartElementFunction -> "FadingRectangle",
   ChartStyle -> Red,
   ImageSize -> 500]
  ]

(* Histogram Magnitude vs. Hufigkeit rendern*)

renderMagnitudeHistogram[data_] :=
 
 Histogram[Map[#[[2]] &, data], {0.1},
  AxesLabel -> {"Magnitude", "Hufigkeit"},
  ImagePadding -> 60,
  ChartElementFunction -> "FadingRectangle",
  ChartStyle -> Blue,
  ImageSize -> 500
  ]

(* Text, Karte und Histogramme rendern*)

renderAll[data_, center_, start_, end_, filename_] :=
 Column[{
   renderTextInfos[data, center, start, end, filename],
   renderEarthquakeMap[data],
   renderIntervalHistogram[data, start, end],
   renderMagnitudeHistogram[data]
   }, Frame -> All]

(* Eingabefelder initialisieren*)
inputCenter = "Japan";
sideLength = 1000;
inputStart = "1.1.2010";
inputEnd = "31.12.2017";
magnitude = 6.0;
filename = "auswertung";
stateMessage = "";

(* Eingabemaske rendern, Eingaben verarbeiten, Ausgabe rendern*)
Grid[{
  (*I.1 Eingabefelder*)
  {Text["Zentrum :"], 
   InputField[Dynamic[inputCenter], String]},
  {Text["Seitenlaenge (km) : "], 
   InputField[Dynamic[sideLength], Number]},
  {Text["Datum Start : "], InputField[Dynamic[inputStart], String]},
  {Text["Datum Ende : "], InputField[Dynamic[inputEnd], String]},
  {Text["Minimale Magnitude : "], 
   InputField[Dynamic[magnitude], Number]},
  {Text["Ausgabe speichern unter : "], 
   InputField[Dynamic[filename], String]},
  
  (* Knopf zur Datenbernahme*)
  {Button["Suche starten",
    
    (***************************)
    (* Aktion bei Knopfdruck:*)
    
    stateMessage = "...Interpretiere Texteingabe fr Zentrum...";
    (*...Texteingaben interpretieren...*)
    
    center = getPositionFromString[inputCenter];
    start = getDateFromString[inputStart];
    end = getDateFromString[inputEnd];
    stateMessage = "...suche nach Erdbeben...";
    (*...Suchanfrage losschicken...*)
    
    data = 
     getEarthquakeData[center, sideLength, start, end, magnitude];
    (*...Wenn Daten gefunden...*)
    If[(data // Length) >= 1,
     stateMessage = 
      ToString[data // Length] <> " Erdbeben gefunden.\n...rendert...";
     NotebookClose[outputNotebook];
     (*...Neues Notebook ffnen...*)
     
     outputNotebook = CreateDocument[
       (*...Komplette grafische Ausgabe in das neu geffnete Notebook \
schreiben*)
       
       ExpressionCell[
        StandardForm[renderAll[data, center, start, end, filename]], 
        "Output"],
       WindowTitle -> "Auswertung", 
       WindowSize -> {900, 900},
       NotebookFileName -> filename];
     stateMessage = "fertig";,
     (*...Wenn keine Daten gefunden...*)
     
     stateMessage = "Keine Erdbeben im Suchbereich gefunden"],
    Method -> "Queued"
    (*Ende Aktion bei Knopfdruck*)
    (****************************)
\
    
    ], SpanFromLeft},
  (* Ausgabefeld fr Statusnachrichten*)
  {Text["Nachricht : "], 
   InputField[Dynamic[stateMessage], String, Enabled -> False]}
  }]
