﻿/*  Copyright 2007 GEO Informatics
 *
 *  GEO WEB Data Management Module  
 *	Create Date:2007.01.23      
 *  Version 0.4.2 - 2007.08.11
/*--------------------------------------------------------------------------*/

var CS_TM67 = {rad:6378160.0,fla:1/298.25,org:121,sca:0.9999,fal:250000.0};
//rad=橢球體長半徑 fla=扁平率 org=經度原點 sca=大小比例尺 fal=平移量

var CS_TM97 = {rad:6378137,fla:1/298.257222101,org:121,sca:0.9999,fal:250000.0};

// GWGeometry Abstract Class
var GWGeometry = Class.create();

GWGeometry.prototype = {
    initialize: function (){
        this.ProjectedCoordinateSystem = 'TWD97';
    }
};

// GWMapObject Abstract Class
var GWMapObject = Class.create();
 
GWMapObject.prototype = {
    initialize:function (){
      this.Id = '';
      this.ClassType = '';  
    },
    
    _SendRequest : function (url,opt,onCom,onFail){
        var options ={};
        if (opt) {
                options = opt;
            } else {
                options.method = 'post';
            }
            
            if (onCom) {    
                options.onComplete = onCom.bind(this);
            }
            
            if (onFail) {    
                options.onFailure = onFail.bind(this);
            }
            // Confirm the Ajax prototype library          
            //var aj = new Ajax.Request(url, options);
    },
    
    _ToQueryString : function (cont){        
        return $H(cont).toQueryString();
    },
    
    _GenerateID : function() {
        var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
        var string_length = 10;
        if (arguments[0]) string_length = arguments[0];
        var maxTry = 10;
        nbTry = 0;
        while (nbTry < 1000) 
        {
          var id = '';
          // generate string
          for (var i=0; i<string_length; i++) 
          {
              var rnum = Math.floor(Math.random() * chars.length);
              id += chars.substring(rnum,rnum+1);
          }
          // check if there
          var elem = $(id);
          if (!elem) {
                var item = document.createElement('input');                
                item.id = id;
                item.type = 'hidden';
                //document.body.appendChild(item);                
                return id;
          }
          nbTry += 1;
        }
        return null;
    },
    
    Destroy:function (){
        elem = $(this.id);
        document.body.removeChild(elem);
        delete this;
    }
};

// GWLngLat Class
var GWLngLat = Class.create();

GWLngLat.prototype = {
    initialize: function(){
        if (arguments[0]) this.Lng = arguments[0]; else this.Lng = 0;
        if (arguments[1]) this.Lat = arguments[1]; else this.Lat = 0;
    },
    
    DistanceFrom : function (other, cs){
        switch (cs) {
            case 'TWD97':
                var a = this.GetTWD97();
                var b = other.GetTWD97();
                return Math.sqrt(Math.pow((a[0]-b[0]),2) + Math.pow((a[1]-b[1]),2));
                break
            case 'China':
                break
        }
    },
    
    GetTWD97 : function (){
        x=this.Lng;
        y=this.Lat;
        x=x/180 * Math.PI;
        y=y/180 * Math.PI;
        var ak=2*CS_TM97.fla-CS_TM97.fla*CS_TM97.fla;
        var dj=ak/(1-ak);
        var fa=Math.pow(Math.tan(y),2);
        var fh=ak*Math.pow(Math.cos(y),2)/(1-ak);
        var ew=(x-CS_TM97.org/180*Math.PI)*Math.cos(y);
        var ft=CS_TM97.rad/Math.sqrt(1-ak*Math.pow(Math.sin(y),2));
        var fu=CS_TM97.rad*((1-ak/4-3*ak*ak/64-5*ak*ak*ak/256)*y-(3*ak/8+3*ak*ak/32+45*ak*ak*ak/1024)*Math.sin(2*y)+(15*ak*ak/256+45*ak*ak*ak/1024)*Math.sin(4*y)-(35*ak*ak*ak/3072)*Math.sin(6*y));
        x=CS_TM97.fal+CS_TM97.sca*ft*(ew+(1-fa+fh)*ew*ew*ew/6+(5-18*fa+fa*fa+72*fh-58*dj)*Math.pow(ew,5)/120);
        y=CS_TM97.sca*(fu+ft*Math.tan(y)*(ew*ew/2+(5-fa+9*fh+4*fh*fh)*Math.pow(ew,4)/24+(61-58*fa+fa*fa+600*fh-330*dj)*Math.pow(ew,6)/720));
        return [x,y];
    },
    
    SetFromTWD97 : function (x,y){
        x=x+828;
        y=y-207;    

        var ak=2*CS_TM97.fla-CS_TM97.fla*CS_TM97.fla;
        var dj=ak/(1-ak);
        var fs=y/CS_TM97.sca;
        var ec=fs/(CS_TM97.rad*(1-ak/4-3*ak*ak/64-5*ak*ak*ak/256));
        var ej=(1-Math.sqrt(1-ak))/(1+Math.sqrt(1-ak));
        var cq=ec+(3*ej/2-27*Math.pow(ej,3)/32)*Math.sin(2*ec)+(21*ej*ej/16-55*Math.pow(ej,4)/32)*Math.sin(4*ec)+151*Math.pow(ej,3)/96*Math.sin(6*ec)+1097*Math.pow(ej,4)/512*Math.sin(8*ec);
        var fo=CS_TM97.rad/Math.sqrt(1-ak*Math.pow(Math.sin(cq),2));
        var fn=CS_TM97.rad*(1-ak)/Math.pow(1-ak*Math.pow(Math.sin(cq),2),1.5);
        var eb=Math.pow(Math.tan(cq),2);
        var dt=dj*Math.pow(Math.cos(cq),2);
        var ex=(x-CS_TM97.fal)/(fo*CS_TM97.sca);
        var di=UCoordSys.t.ed/180*Math.PI+(ex-(1+2*eb+dt)*ex*ex*ex/6+(5-2*dt+28*eb-3*dt*dt+8*dj+24*eb*eb)*Math.pow(ex,5)/120)/Math.cos(cq);
        var dh=cq-(fo*Math.tan(cq)/fn)*(ex*ex/2-(5+3*eb+10*dt-4*dt*dt-9*dj)*Math.pow(ex,4)/24+(61+90*eb+298*dt+45*eb*eb-252*dj-3*dt*dt)*Math.pow(ex,6)/720);
        di=di/Math.PI*180;
        dh=dh/Math.PI*180;    
        this.Lng = di;
        this.Lat = dh;
    },
    
    // 經緯度十進位轉換為度分秒
    DecToDeg : function(){    
        var m, s;
        var Lng, Lat;
        Lng = Math.floor(this.Lng) + "° ";
        m = (this.Lng - Math.floor(this.Lng)) * 60;
        Lng += Math.floor(m) + "' ";
        s = (m - Math.floor(m)) * 60;
        Lng += s.toFixed(1) + '"';
        
        Lat = Math.floor(this.Lat) + "° ";
        m = (this.Lat - Math.floor(this.Lat)) * 60;
        Lat += Math.floor(m) + "' ";
        s = (m - Math.floor(m)) * 60;
        Lat += s.toFixed(1) + '"';
        return [Lng,Lat];    
    }
};


// GWEnvelope(西北角坐標, 東南角坐標)
var GWEnvelope = Class.create();

GWEnvelope.prototype = {
    initialize: function(){
        this.NW = arguments[0]? arguments[0] : new GWLngLat(); 
        this.SE = arguments[1]? arguments[1] : new GWLngLat(); 
    },
    
    GetArea : function (cs){
        var a, b;
        if (cs == 'TM67') {
            a = this.NW.getTM97();
            b = this.SE.getTM97();
        } 
        return (Math.abs(a[0]-b[0]) * Math.abs(a[1]-b[1]));
    },
    
    GetCenter : function (){
        return new GWLngLat(((this.NW.Lng + this.SE.Lng)/2),((this.NW.Lat + this.SE.Lat)/2));
    },

    GetSouthEast : function (){
        return this.SE;
    },

    GetNorthWest : function (){
        return this.NW;
    },

    SetSouthEast : function (nw){
        this.NW = nw;
    },

    SetNorthWest : function (se){
        this.SE = se;
    },

    SetEnvelope : function (nw,se){
        this.NW = nw;
        this.SE = se;
    },

    MergeWith : function (other){    
        var maxLng, maxLat, minLng, minLat;
        maxLng = Math.max(this.SE.Lng,other.SE.Lng);
        maxLat = Math.max(this.NW.Lat,other.NW.Lat);
        minLng = Math.min(this.NW.Lng,other.NW.Lng);
        minLat = Math.min(this.SE.Lat,other.SE.Lat);
        return new GWEnvelope(new GWLngLat(minLng,maxLat),new GWLngLat(maxLng, minLat));
    }
};


// Icon Style Object
function GWIconStyle(i,s) {
    this.Icon = i;
    this.Shad = s;
};

var DEFAULTICONSTYLE = new GWIconStyle(new GWMapIcon('Images/MIcon01.png',26,43,5,20), new GWMapIcon('Images/MIcon02.png',26,43,5,20));
var EMPTYICONSTYLE = new GWIconStyle(new GWMapIcon('',0,0,0,0), new GWMapIcon('',0,0,0,0));


// Geometry Feature Class - Super Class
var GWFeature = Class.create();
GWFeature.prototype = Object.extend(new GWGeometry(),{
    initialize: function(){
        this.Fid = -1;
        this.Geometry = new Array();        // GWLngLat Object
        this.Envelope = new GWEnvelope();
        this.Attribute = new Object();
        this.AttributeTemplate  = new Object();        

        if (arguments[1]) this.Attribute = arguments[1];
        if (arguments[2]) this.AttributeTemplate = new Template(arguments[2]);
        
    },
    
    _CreateEnvelope : function(){
        var maxLng, maxLat, minLng, minLat;
        if (this.Geometry.length > 0){
            maxLng = this.Geometry[0].Lng;
            maxLat = this.Geometry[0].Lat;
            minLng = this.Geometry[0].Lng;
            minLat = this.Geometry[0].Lat;
            for (var i = 0; i < this.Geometry.length; i ++ ) {
                maxLng = Math.max(maxLng,this.Geometry[i].Lng);
                maxLat = Math.max(maxLat,this.Geometry[i].Lat);
                minLng = Math.min(minLng,this.Geometry[i].Lng);
                minLat = Math.min(minLat,this.Geometry[i].Lat);
            }
            this.Envelope.SetEnvelope(new GWLngLat(minLng,maxLat),new GWLngLat(maxLng, minLat));
        }
    },
    
    GetAttribute : function (n){
        var a = this.Attribute;
        var b = (typeof($H(a).values()[$H(a).keys().indexOf(n)])!='undefined') ? $H(a).values()[$H(a).keys().indexOf(n)] : null;
        return b;
    },
    
    GetEnvelope: function(){
        return this.Envelope;
    },
    
    GetGeometry : function (){
        return this.Geometry;
    },
    
    GetFormattedAttribute : function (){
        var t = this.AttributeTemplate;
        var a = this.Attribute;
        return Try.these(function() { return t.evaluate(a)}) || '';
    },
    
    SetFid: function(id){
        this.Fid = id;
    }
});

// GWPoint Feature Class
var GWPointFeature = Class.create();
GWPointFeature.prototype = Object.extend(new GWFeature(),{
    initialize:function(){
        GWFeature.prototype.initialize.apply(this, arguments);
        this.ClassType          = 'GWPointFeature';
        this.Symbol             = DEFAULTICONSTYLE;
        this.HasInfo            = 0;
        this.BtnType            = 0;
        if (arguments[0]){
            this.Geometry.push(arguments[0]);
        } else {
            this.Geometry.push(new GWLngLat());
        }  
        if (arguments[3]) this.SetBtnType(arguments[3]);
        if (arguments[4]) this.SetSymbol(arguments[4]);
        this._CreateEnvelope();
    },
    
    _CreateEnvelope : function (){
        this.Envelope.SetEnvelope(this.Geometry[0],this.Geometry[0]);
    },
    
    SetBtnType: function (type){
        this.BtnType = type;
    },
    
    SetSymbol : function (IS){
        this.Symbol = IS;
    },   
    
    SetGeometry : function (pt){
        this.Geometry = new Array();
        this.Geometry.push(pt);
        this._CreateEnvelope();
    }
});


// GWPolyLine Feature Class (Polyline, Polygon, Circle)
var GWPolyLineFeature = Class.create();
GWPolyLineFeature.prototype = Object.extend(new GWFeature(),{
    initialize:function(){
        GWFeature.prototype.initialize.apply(this, arguments);
        this.ClassType  = 'GWPolyLineFeature';
        this.LineStyle  = {Width:5,Color:{r:0,g:0,b:200,a:0.4}};
        this.NodeStyle  = {Size:3,Color:{r:0,g:0,b:200,a:0.4}};
        this.Line       = new Object();
        this.StereoType = 0;                                        // Macth the type in GWPolyLine 
        if (arguments[0]) this.SetGeometryByArray(arguments[0]);
        if (arguments[3]) this.SetStereoType(arguments[3]);    
        this._CreateEnvelope();            
    },
    
    _CreateGWPolyLine: function(){
        if (this.GetNodesCount() > 1) {
            var pt = this.Geometry[0];
            var t = new Template('rgba(#{r},#{g},#{b},#{a})');
            var l = new GWPolyLine(new GWPoint(pt.Lng,pt.Lat,this.NodeStyle.Size,t.evaluate(this.NodeStyle.Color)),this.LineStyle.Width,t.evaluate(this.LineStyle.Color),this.StereoType);
            for (var i = 1; i < this.GetNodesCount();i++){
                pt = this.Geometry[i];
                l.AddPoint(new GWPoint(pt.Lng,pt.Lat,this.NodeStyle.Size,t.evaluate(this.NodeStyle.Color)));
            }
            this.Line = l;
        }
    },
    
    AddNode : function (pt){
        this.Geometry.push(pt);
        this._CreateEnvelope();
        this._CreateGWPolyLine();
    },
    
    AddNodes : function (pts){        
        this.Geometry = this.Geomtry.concat(pts);
        this._CreateEnvelope();
        this._CreateGWPolyLine();
    },
          
    EditNode: function (i,g){
        this.Geometry[i] = g;
        this._CreateEnvelope();
        this._CreateGWPolyLine();
    },
    
    GetArea: function(ps){
        switch (this.StereoType){
            case 0:
                return 0;
            case 1,2:
                //計算多邊形面積
                break;
            case 3,4:
                //計算圓形面積
                break;
        }
    },
    
    GetLength: function (ps){
        if (typeof(ps) == 'undefined') ps = this.ProjectedCoordinateSystem;
        var dist = 0;
        for (var i = 0; i < this.GetNodesCount()-1;i++)
            dist += this.Geometry[i].DistanceFrom(this.Geometry[i+1],ps);
        return dist;
    },
    
    GetNodesCount: function(){
        return this.Geometry.length;
    },
    
    GetGWPolyLineNode: function (obj){
        var a = new Array();
        var Pt = obj.StPoint;
        a.push([Pt.iX,Pt.iY]);
        while(1)
        {
          a.push([Pt.iX,Pt.iY]);
          if(Pt == obj.LtPoint)
            break;
          Pt = Pt.oNextPoint;
        }
        return a;
    },  
    
    SetGeometryByGWPolyLine: function (obj){
        var a = this.GetGWPolyLineNode(obj);
        this.SetGeometryByArray(a);
    },
    
    SetGeometryByArray: function (a){
        this.Geometry = new Array();
        for (var i=0;i<a.length;i++)
            this.Geometry.push(new GWLngLat(a[i][0],a[i][1]));
        this._CreateEnvelope();
        this._CreateGWPolyLine();
    },
    
    SetLineStyle: function (w,c){
        this.LineStyle.Width = w;
        this.LineStyle.Color = c;
        this._CreateGWPolyLine();
    },
    
    SetNodeStyle: function (s,c){
        this.NodeStyle.Size = s;
        this.NodeStyle.Color = c;
        this._CreateGWPolyLine();
    },
    
    SetStereoType: function (t){
        this.StereoType = t;  
        this._CreateGWPolyLine();
    },
    
    RemoveFirstNode: function(){
        this.Geometry.shift();
        this._CreateEnvelope();
        this._CreateGWPolyLine();
    },
    
    RemoveLastNode: function(){
        this.Geometry.pop();
        this._CreateEnvelope();
        this._CreateGWPolyLine();
    }
});



// GWPolygon Feature Class

// Multipoint Feature Class

// Circle Feature Class


// Layer Class - SuperClass
var GWLayer = Class.create();

GWLayer.prototype = Object.extend(new GWMapObject(),{
    initialize:function(){
        GWMapObject.prototype.initialize.apply(this, arguments);
        this.Id             = this._GenerateID();
        this.Name           = '';
        this.Index          = 0;
        this.Envelope       = new GWEnvelope();
        this.Map            = new Object();
        this.Attribute      = {};
        //this.layertype      = 0;                  // {0:point,1:polyline,2:polygon}
        this.FeatureMembers = new Array();          // Feature 成員
        this.IsFeatureLOD   = false;                // 是否啟用Feature LOD功能
        //this.BufferMembers  = new Array();        // [{fid,x,y}]        
        this.QueryParams    = new Object();
        this.QueryUrl       = ''; 
        this.QueryMethod    = 'post';
        this.DynamicReflash = false;
        this.Visible        = true;
        this.MaxScale       = 10;
        //this.searchBean     = '';
        this.MaxCount       = 100;
        //this.allrange       = false;
        //this.CusAtt         = false;
        //this._DebugObj      = null;
        this.HasInfo        = 0;
        
        this.Events = {
            NewIndex:       function (){},
            IsLoadingData:  function (){},  
            IsLoadedData:   function (){},
            IsOverlayed:    function (){}
        };        
        //this.ClassType = 'Layer';
    },
    
    SetEventListener : function (evt, handler){
        if (typeof(handler) == 'function') {
            switch(evt)
            {
              case 'IsLoadingData':
                this.Events.IsLoadingData = handler;
                break;
	          case 'IsLoadedData':
                this.Events.IsLoadedData = handler;
                break;
              case 'IsOverlayed':
                this.Events.IsOverlayed = handler;
                break;
              default:
                ;
            }
        }
    },

    _CreateEnvelope : function (){   
        if (this.GetFeatureCount() > 0) {
            this.Envelope.SetEnvelope(this.FeatureMembers[0].Envelope.GetNorthWest(),this.FeatureMembers[0].Envelope.GetSouthEast());
            for (i=0;i<this.GetFeatureCount();i++)
                this.Envelope = this.Envelope.MergeWith(this.FeatureMembers[i].Envelope);
        }
    },

    AddFeature : function (f){
        this.FeatureMembers.push(f);
        this._CreateEnvelope();
    },

    GetAttribute: function (n){
        var a = this.Attribute;
        var b = (typeof($H(a).values()[$H(a).keys().indexOf(n)])!='undefined') ? $H(a).values()[$H(a).keys().indexOf(n)] : null;
        return b;
    },
    
    GetEnvelope: function(){
        return this.Envelope;
    },
    
    GetFeatureCount : function (){
        return this.FeatureMembers.length;
    },

    GetIndexByFid: function (fid){
        for (var i=0; i < this.GetFeatureCount();i++)
            if (this.FeatureMembers[i].Fid==fid) return i;    
    },

    SetMap : function (m){
        this.Map = m;
    },
    
    SetAttribute: function(a){
        this.Attribute = a;
    },
    
    SetVisibility: function (b){
        this.Visible = b;
        if (b) this.OverlayFeature(); else this.HideAllFeatures();
    }, 
    
    OverlayFeature: function(){},
    
    HideFeature : function (){},

    HideAllFeatures : function (){},

    RemoveFeature : function (){},

    RemoveAllFeatures : function (){},
    
    ZoomToExtent: function(){
        if (this.Map) {
            //this.Map.MoveToRXY(x,y,s,false);
        }
    },
    
    Destroy : function (){
        this.RemoveAllFeatures();
        delete this;
    }    
});


// GWPoint Layer
var GWPointLayer = Class.create();

GWPointLayer.prototype = Object.extend(new GWLayer(),{
    initialize:function(){
        GWLayer.prototype.initialize.apply(this, arguments);   
        this.Layertype     = 0;
        this.ClassType     = 'PointLayer';
        this.SymbolStyle   = null;
        this.BtnType       = 0;
        this.Name          = arguments[0];
             
    },
    
    OverlayFeature : function (){
        if (!this.Map) return 'Please set GWMap object firstly!'; else var m = this.Map;    
        if (this.GetFeatureCount() < 1) return 'No Feature in this Layer!';    
        if (!this.Visible) return 'This layer is set to be hidden.';
        
        this.HideAllFeatures();
        
        this.FeatureMembers.each(function(f){
            var pt = f.GetGeometry()[0];
            var c = f.GetFormattedAttribute();
            var id = (f.GetAttribute("id")!=null) ? f.GetAttribute("id") : '';
            f.Fid = m.AddPlacard(f.BtnType,f.Symbol.Icon,f.Symbol.Shad,1,pt.Lng,pt.Lat,c,'',id);
        });
        this.Map.ReflashPlacard();
    },
    
    SetSymbolStyle : function (is) {
        this.SymbolStyle = is;
    },

    SetAllFeaturesBtnType: function (type){
        this.BtnType = type;
        this.FeatureMembers.each(function(f){f.BtnType = type;});        
    },

    HideFeature : function (feature){
        if (this.FeatureMembers.indexOf(feature)>=0){
            this.Map.RemovePlacard(feature.Fid);   
            this.Map.ReflashPlacard(); 
        }
    },

    HideAllFeatures : function (){
        var m = this.Map;
        this.FeatureMembers.each(function (f){if (f.Fid>=0) m.RemovePlacard(f.Fid);});
        this.Map.ReflashPlacard();
    },

    RemoveFeature : function (feature){
        if (this.FeatureMembers.indexOf(feature)>=0){
            this.Map.RemovePlacard(feature.Fid);   
            this.Map.ReflashPlacard(); 
            this.FeatureMembers = RemoveFromArray(this.FeatureMembers,feature);
        }
    },

    RemoveAllFeatures : function (){
        var m = this.Map;        
        this.FeatureMembers.each(function (f){m.RemovePlacard(f.Fid);});
        this.FeatureMembers = new Array();
        this.Map.ReflashPlacard();
    }    
});

// GWPolyline Layer
var GWPolyLineLayer = Class.create();

GWPolyLineLayer.prototype = Object.extend(new GWLayer(),{
    initialize:function(){
        GWLayer.prototype.initialize.apply(this, arguments);
        this.Layertype     = 1;
        this.ClassType     = 'PolylineLayer';        
        this.StereoType    = 0;
        this.Name          = arguments[0];        
        if (arguments[1]) this.StereoType = arguments[1];
    },
    
    OverlayFeature : function (){
        if (!this.Map) return 'Please set GWMap object firstly!'; else var m = this.Map;    
        if (this.GetFeatureCount() < 1) return 'No Feature in this Layer!';
        if (!this.Visible) return 'This layer is set to be hidden.';
        this.HideAllFeatures();
        this.FeatureMembers.each(function(f){
            f.Fid = m.AddPolyLine(f.Line);
        });
        this.Map.ReflashPolyLine();
    },

    HideFeature : function (feature){
        if (this.FeatureMembers.indexOf(feature)>=0){
            this.Map.RemovePolyLine(feature.Fid);
            this.Map.ReflashPolyLine(); 
        }
    },

    HideAllFeatures : function (){
        var m = this.Map;
        this.FeatureMembers.each(function (f){m.RemovePolyLine(f.Fid);});
        this.Map.ReflashPolyLine();
    },
    
    SetAllFeaturesLineStyle: function(w,c){
        this.FeatureMembers.each(function(f){f.SetLineStyle(w,c);});
        //if (this.Visible) this.OverlayFeature();
    },
    
    SetAllFeaturesNodeStyle: function(s,c){
        this.FeatureMembers.each(function(f){f.SetNodeStyle(s,c);});
        //if (this.Visible) this.OverlayFeature();
    },

    RemoveFeature : function (feature){
        if (this.FeatureMembers.indexOf(feature)>=0){
            this.Map.RemovePlacard(feature.Fid);        
            this.Map.ReflashPolyLine();
            this.FeatureMembers = RemoveFromArray(this.FeatureMembers,feature);
        }
    },

    RemoveAllFeatures : function (){
        var m = this.Map;        
        this.FeatureMembers.each(function (f){if (f.Fid>=0) m.RemovePolyLine(f.Fid);});
        this.FeatureMembers = new Array();
        this.Map.ReflashPolyLine();
    }
}); 


// 底層共用函數
function RemoveFromArray(a,t){
    if (a.indexOf(t) >= 0) 
        return a.slice(0,a.indexOf(t)).concat(a.slice(a.indexOf(t)+1,a.length)); 
    else
        return a;
}