<?PHP

class LatLongPoints extends Plugin {

    function Register()
    {
        $this->Name = "Latitude/Longitude Points";
        $this->Version = "1.1.0";
        $this->Description = "The Latitude/Longitude Points plugin makes any"
                ." Point metadata fields accept input and display in common"
                ." latitude/longitude format (e.g. <i>43&deg; 21' 10&quot; N</i>).";
        $this->Author = "Internet Scout";
        $this->Url = "http://scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array("CWISCore" => "2.1.0");
        $this->CfgSetup["FieldOne"] = array(
                "Type" => "MetadataField",
                "Label" => "Lat/Long Field",
                "Help" => "Point field to accept and display"
                        ." latitude/longitude coordinates.",
                "FieldTypes" => MetadataSchema::MDFTYPE_POINT,
                );
        $this->CfgSetup["FieldTwo"] = $this->CfgSetup["FieldOne"];
        $this->CfgSetup["FieldThree"] = $this->CfgSetup["FieldOne"];
    }

    function HookEvents()
    {
        return array(
                "EVENT_FIELD_DISPLAY_FILTER" => "LatLongDecimalToDegrees",
                "EVENT_PRE_FIELD_EDIT_FILTER" => "LatLongDecimalToDegrees",
                "EVENT_POST_FIELD_EDIT_FILTER" => "LatLongDegreesToDecimal",
                );
    }

    function LatLongDecimalToDegrees($Field, $Resource, $Value)
    {
        global $SysConfig;

        $CharacterSet = $SysConfig->DefaultCharacterSet();

        $ReturnValue = array(
                "Field" => $Field,
                "Resource" => $Resource,
                "Value" => $Value);
        $LatLongFields = array(
                $this->ConfigSetting("FieldOne"),
                $this->ConfigSetting("FieldTwo"),
                $this->ConfigSetting("FieldThree"),
                );
        if (in_array($Field->Id(), $LatLongFields))
        {
            foreach (array("X", "Y") as $Axis)
            {
                if (floatval($Value[$Axis]))
                {
                    $Coord = $Value[$Axis];
                    $Degrees = floor(abs($Coord));
                    $Minutes = floor((abs($Coord) - $Degrees) * 60);
                    $Seconds = round((abs($Coord)
                            - $Degrees - ($Minutes / 60)) * 3600);
                    $DegreeSymbol = html_entity_decode(
                        "&deg; ",
                        ENT_COMPAT,
                        $CharacterSet);

                    $ReturnValue["Value"][$Axis] =
                            $Degrees.$DegreeSymbol
                            .$Minutes."' ".$Seconds."\" "
                            .(($Coord >= 0) ? (($Axis == "X") ? "N" : "E")
                            : (($Axis == "X") ? "S" : "W"));
                }
            }
        }
        return $ReturnValue;
    }

    function LatLongDegreesToDecimal($Field, $Resource, $Value)
    {
        $ReturnValue = array(
                "Field" => $Field,
                "Resource" => $Resource,
                "Value" => $Value);
        $LatLongFields = array(
                $this->ConfigSetting("FieldOne"),
                $this->ConfigSetting("FieldTwo"),
                $this->ConfigSetting("FieldThree"),
                );
        if (in_array($Field->Id(), $LatLongFields))
        {
            # for each of the coordinate
            foreach (array("X", "Y") as $Axis)
            {
                # remove all extraneous characters
                $Value = strtoupper(trim($ReturnValue["Value"][$Axis]));
                $Value = preg_replace("/[^0-9SNEW.\s-]/", " ", $Value);

                # split up into individual components
                $Pieces = preg_split("/\s+/", $Value);

                # if components were found
                if (count($Pieces) && floatval($Pieces[0]))
                {
                    # calculate fractional value from remaining components
                    $NewValue = 0;
                    $Divisor = 1;
                    foreach ($Pieces as $Piece)
                    {
                        $NewValue += $Piece / $Divisor;
                        $Divisor *= 60;
                    }

                    # flip sign if direction indicates
                    if ((substr($Piece, -1) == "W") || (substr($Piece, -1) == "S"))
                    {
                        $NewValue = 0 - $NewValue;
                    }

                    # save new decimal value
                    $ReturnValue["Value"][$Axis] = $NewValue;
                }
            }
        }
        return $ReturnValue;
    }
}

?>
