/**
 * 
 */
package org.mwc.cmap.core.custom_widget;

import java.text.ParseException;
import java.util.Vector;

import org.eclipse.nebula.widgets.formattedtext.FormattedText;
import org.eclipse.nebula.widgets.formattedtext.MaskFormatter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SegmentEvent;
import org.eclipse.swt.events.SegmentListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.mwc.cmap.core.CorePlugin;
import org.mwc.cmap.gridharness.data.base60.Sexagesimal;
import org.mwc.cmap.gridharness.data.base60.SexagesimalFormat;

import MWC.GenericData.WorldLocation;

/**
 * This is a custom composite to specify the world location
 * in lat and long
 * @author Ayesha
 *
 */
public class CWorldLocation extends Composite
{
  private FormattedText myLatitude;

  private FormattedText myLongitude;
  
  private Vector<LocationModifiedListener> _locationModifiedListeners = new Vector<>();

  public CWorldLocation(Composite parent, int style)
  {
    super(parent, style);
    final GridLayout rows = new GridLayout(2,true);
    rows.marginLeft = rows.marginRight = 0;
    rows.marginTop = rows.marginBottom = 0;
    setLayout(rows);
    GridData gd = new GridData();
    gd.heightHint=40;
    setLayoutData(gd);
    myLatitude = new FormattedText(this, SWT.BORDER);
    myLongitude = new FormattedText(this, SWT.BORDER);
    GridData data1 = new GridData();
    data1.widthHint = 90;
    myLatitude.getControl().setLayoutData(data1);
    GridData data2 = new GridData();    
    data2.widthHint = 100;
    myLongitude.getControl().setLayoutData(data2);
    myLatitude.setFormatter(new IgnoreTabsMaskFormatter(getFormat().getNebulaPattern(false)));
    myLongitude.setFormatter(new IgnoreTabsMaskFormatter(getFormat().getNebulaPattern(true)));

    myLatitude.getControl().addSegmentListener(new SegmentListener()
    {
      @Override
      public void getSegments(SegmentEvent event)
      {
        valueModified(event);
        
      }  
     
    });
    myLongitude.getControl().addSegmentListener(new SegmentListener()
    {
      @Override
      public void getSegments(SegmentEvent event)
      {
        valueModified(event);
        
      }  
     
    });

  }
  
  
  public void addLocationModifiedListener(LocationModifiedListener listener) {
    _locationModifiedListeners.add(listener);
  }
 
  
  private void valueModified(SegmentEvent e)
  {
    LocationModifiedEvent event = new LocationModifiedEvent(e.getSource(),myLatitude.getValue(),myLongitude.getValue());
    for(LocationModifiedListener listener:_locationModifiedListeners) {
      listener.modifyValue(event);
    }
    
  }
  

  private SexagesimalFormat getFormat() {
    //intentionally reevaluated each time
    return CorePlugin.getDefault().getLocationFormat();
  }
  
  private static class IgnoreTabsMaskFormatter extends MaskFormatter {

    public IgnoreTabsMaskFormatter(final String mask) {
      super(mask);
    }

    @Override
    public void verifyText(final VerifyEvent e) {
      if (ignore) {
        return;
      }
      if (e.keyCode == SWT.TAB) {
        e.doit = false;
        return;
      }
      super.verifyText(e);
    }
  }
  public WorldLocation getValue() {
    if (!myLatitude.isValid() || !myLongitude.isValid()) {
      return null;
    }
    final String latitudeString = (String) myLatitude.getFormatter().getDisplayString();
    final String longitudeString = (String) myLongitude.getFormatter().getDisplayString();

    Sexagesimal latitude;
    Sexagesimal longitude;
    try {
      latitude = getFormat().parse(latitudeString, false);
      longitude = getFormat().parse(longitudeString, true);
    } catch (final ParseException e) {
      //thats ok, formatter does not know the hemisphere characters
      return null;
    }

    final WorldLocation location = new WorldLocation(latitude.getCombinedDegrees(), longitude.getCombinedDegrees(),0);
    return location;
  }

  public void setValue(final WorldLocation location) {
    final Sexagesimal latitude = getFormat().parseDouble(location.getLat());
    final Sexagesimal longitude = getFormat().parseDouble(location.getLong());

    myLatitude.setValue(getFormat().format(latitude, false));
    myLongitude.setValue(getFormat().format(longitude, true));
  }
}

@@ -301,23 +301,22 @@
 .events.
-Segment
+Modify
 Event;%0D%0A
@@ -345,23 +345,22 @@
 .events.
-Segment
+Modify
 Listener
@@ -1971,39 +1971,38 @@
 getControl().add
-Segment
+Modify
 Listener(new Seg
@@ -1990,39 +1990,38 @@
 ifyListener(new 
-Segment
+Modify
 Listener()%0D%0A    
@@ -2006,39 +2006,36 @@
 ModifyListener()
-%0D%0A   
  %7B
+%0D%0A
 %0D%0A      @Overrid
@@ -2055,35 +2055,33 @@
 ic void 
-getSegments(Segment
+modifyText(Modify
 Event ev
@@ -2126,44 +2126,31 @@
 vent
-);%0D%0A        %0D%0A      %7D  %0D%0A     %0D%0A    
+.getSource());%0D%0A      %7D
 %7D);%0D
@@ -2149,35 +2149,34 @@
    %7D%7D);%0D%0A    myL
-ong
+at
 itude.getControl
@@ -2181,23 +2181,22 @@
 ol().add
-Segment
+Modify
 Listener
@@ -2200,23 +2200,22 @@
 ner(new 
-Segment
+Modify
 Listener
@@ -2220,15 +2220,12 @@
 er()
-%0D%0A   
  %7B
+%0D%0A
 %0D%0A  
@@ -2261,27 +2261,25 @@
 oid 
-getSegments(Segment
+modifyText(Modify
 Even
@@ -2328,51 +2328,36 @@
 vent
-);%0D%0A        %0D%0A      %7D  %0D%0A     %0D%0A    
+.getSource());%0D%0A      %7D
 %7D);%0D%0A
-%0D%0A
   %7D%0D
@@ -2361,20 +2361,16 @@
  %7D%0D%0A  %0D%0A
-  %0D%0A
   public
@@ -2533,21 +2533,26 @@
 ied(
-SegmentEvent 
+final Object sourc
 e)%0D%0A
@@ -2620,21 +2620,14 @@
 ent(
-e.getS
+s
 ource
-()
 ,myL
@@ -2787,22 +2787,16 @@
 %0A    %7D%0D%0A
-    %0D%0A
   %7D%0D%0A  %0D

Switch to tracking different event, since segment modified is only thrown on MS Windows